diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1e17a21f4b..92c421b98c 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.24", + "VARIANT": "1.26", // Options "INSTALL_NODE": "false", "NODE_VERSION": "lts/*" diff --git a/.github/workflows/adapter-code-coverage-report.yml b/.github/workflows/adapter-code-coverage-report.yml new file mode 100644 index 0000000000..c286ee6c6b --- /dev/null +++ b/.github/workflows/adapter-code-coverage-report.yml @@ -0,0 +1,77 @@ +name: Adapter Code Coverage Report + +on: + workflow_run: + workflows: ["Adapter Code Coverage"] + types: [completed] + +permissions: + pull-requests: write + contents: write + +jobs: + report-coverage: + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Download Coverage Artifacts + uses: actions/download-artifact@v4 + with: + name: coverage-results + path: coverage-results + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + + - name: Read PR Metadata + id: pr_metadata + run: | + echo "pr_number=$(cat coverage-results/pr-metadata/pr_number)" >> $GITHUB_OUTPUT + echo "head_sha=$(cat coverage-results/pr-metadata/head_sha)" >> $GITHUB_OUTPUT + echo "directories=$(cat coverage-results/pr-metadata/directories.json)" >> $GITHUB_OUTPUT + echo "coverage_dir=$(pwd)/coverage-results" >> $GITHUB_OUTPUT + + - name: Checkout Coverage Preview Branch + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: coverage-preview + repository: prebid/prebid-server + path: preview-repo + + - name: Upload Coverage Results + id: commit_coverage + run: | + timestamp=$(date +%s) + directory=preview-repo/.github/preview/${{ github.event.workflow_run.id }}_${timestamp} + mkdir -p $directory + cp -r coverage-results/*.html $directory/ + cd preview-repo + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git add .github/preview/* + git commit -m 'Add coverage files for run ${{ github.event.workflow_run.id }}' + git push origin coverage-preview + echo "remote_coverage_preview_dir=.github/preview/${{ github.event.workflow_run.id }}_${timestamp}" >> $GITHUB_OUTPUT + + - name: Add Coverage Summary To Pull Request + if: steps.commit_coverage.outputs.remote_coverage_preview_dir != '' + uses: actions/github-script@v7 + with: + script: | + const utils = require('./.github/workflows/helpers/pull-request-utils.js') + const helper = utils.coverageHelper({ + github, context, + headSha: '${{ steps.pr_metadata.outputs.head_sha }}', + tmpCoverageDir: '${{ steps.pr_metadata.outputs.coverage_dir }}', + remoteCoverageDir: '${{ steps.commit_coverage.outputs.remote_coverage_preview_dir }}', + prNumber: ${{ steps.pr_metadata.outputs.pr_number }} + }) + const adapterDirectories = JSON.parse('${{ steps.pr_metadata.outputs.directories }}') + await helper.AddCoverageSummary(adapterDirectories) diff --git a/.github/workflows/helpers/pull-request-utils.js b/.github/workflows/helpers/pull-request-utils.js index 73c8039647..70e8570e4b 100644 --- a/.github/workflows/helpers/pull-request-utils.js +++ b/.github/workflows/helpers/pull-request-utils.js @@ -361,7 +361,7 @@ class coverageHelper { this.owner = input.context.repo.owner this.repo = input.context.repo.repo this.github = input.github - this.pullRequestNumber = input.context.payload.pull_request.number + this.pullRequestNumber = input.prNumber || input.context.payload.pull_request.number this.headSha = input.headSha this.previewBaseURL = `https://htmlpreview.github.io/?https://github.com/${this.owner}/${this.repo}/coverage-preview/${input.remoteCoverageDir}` this.tmpCoverDir = input.tmpCoverageDir diff --git a/.github/workflows/scripts/codepath-notification b/.github/workflows/scripts/codepath-notification index 8a3bae8dac..b917c6d201 100644 --- a/.github/workflows/scripts/codepath-notification +++ b/.github/workflows/scripts/codepath-notification @@ -19,3 +19,4 @@ adapters/ix|imp_ix|ix.json|ix.yaml: pdu-supply-prebid@indexexchange.com medianet: prebid@media.net gumgum: prebid@gumgum.com kargo: kraken@kargo.com +proxistore: proxistore-technics@proxistore.com diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index d3831d8044..f0a4ac68d8 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -20,7 +20,7 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} - name: Run Trivy - uses: aquasecurity/trivy-action@master + uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 with: scan-type: 'fs' ignore-unfixed: true diff --git a/.github/workflows/validate-merge.yml b/.github/workflows/validate-merge.yml index ca633d4746..64a611f537 100644 --- a/.github/workflows/validate-merge.yml +++ b/.github/workflows/validate-merge.yml @@ -12,7 +12,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: 1.24.0 + go-version: 1.26.2 - name: Checkout Merged Branch uses: actions/checkout@v4 diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index df71d61612..b8d5ea7a55 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -10,7 +10,7 @@ jobs: validate: strategy: matrix: - go-version: [1.23.x, 1.24.x] + go-version: [1.25.x, 1.26.x] os: [ubuntu-latest] runs-on: ${{ matrix.os }} @@ -31,3 +31,4 @@ jobs: ./validate.sh --nofmt --cov --race 10 env: GO111MODULE: "on" + GOTOOLCHAIN: local diff --git a/Dockerfile b/Dockerfile index fe7cec5e16..4f0948351b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,13 @@ -FROM ubuntu:22.04 AS build +# BASE_IMAGE allows overriding the base image so the build can pull from an +# internal mirror when docker.io is unreachable. Defaults to upstream ubuntu:22.04. +ARG BASE_IMAGE=ubuntu:22.04 +FROM ${BASE_IMAGE} AS build RUN apt-get update && \ apt-get -y upgrade && \ apt-get install -y --no-install-recommends wget ca-certificates WORKDIR /tmp -RUN wget https://dl.google.com/go/go1.24.0.linux-amd64.tar.gz && \ - tar -xf go1.24.0.linux-amd64.tar.gz && \ +RUN wget https://dl.google.com/go/go1.26.2.linux-amd64.tar.gz && \ + tar -xf go1.26.2.linux-amd64.tar.gz && \ mv go /usr/local RUN mkdir -p /app/prebid-server/ WORKDIR /app/prebid-server/ @@ -24,9 +27,9 @@ 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/v3/version.Ver=`git describe --tags | sed 's/^v//'` -X github.com/prebid/prebid-server/v3/version.Rev=`git rev-parse HEAD`" . +RUN go build -mod=vendor -ldflags "-X github.com/prebid/prebid-server/v4/version.Ver=`git describe --tags | sed 's/^v//'` -X github.com/prebid/prebid-server/v4/version.Rev=`git rev-parse HEAD`" . -FROM ubuntu:22.04 AS release +FROM ${BASE_IMAGE} AS release LABEL maintainer="hans.hjort@xandr.com" WORKDIR /usr/local/bin/ COPY --from=build /app/prebid-server . diff --git a/Makefile b/Makefile index 8b68afe3be..327a4acd23 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ test: deps ifeq "$(adapter)" "" ./validate.sh else - go test github.com/prebid/prebid-server/v3/adapters/$(adapter) -bench=. + go test github.com/prebid/prebid-server/v4/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 0aa629ebc2..2323db2d09 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Ensure that you deploy the `/static` directory, as Prebid Server requires those ## Developing -Prebid Server requires [Go](https://go.dev) version 1.23 or newer. You can develop on any operating system that Go supports; however, please note that our helper scripts are written in bash. +Prebid Server requires [Go](https://go.dev) version 1.26.2 or newer. You can develop on any operating system that Go supports; however, please note that our helper scripts are written in bash. 1. Clone The Repository ``` bash diff --git a/account/account.go b/account/account.go index 0087548cc7..87597e5fed 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/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" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/util/iputil" + "github.com/prebid/prebid-server/v4/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 c8b17b53ff..15963e3d0b 100644 --- a/account/account_test.go +++ b/account/account_test.go @@ -6,13 +6,13 @@ import ( "fmt" "testing" - "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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/util/iputil" + "github.com/prebid/prebid-server/v4/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 45a7ea3656..100ada6691 100644 --- a/adapters/33across/33across.go +++ b/adapters/33across/33across.go @@ -7,11 +7,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type TtxAdapter struct { diff --git a/adapters/33across/33across_test.go b/adapters/33across/33across_test.go index 3ed177deac..87880b0d99 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/33across/params_test.go b/adapters/33across/params_test.go index 8517c5939a..dd05a28d77 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 1096955965..8dae76f39d 100644 --- a/adapters/aax/aax.go +++ b/adapters/aax/aax.go @@ -7,11 +7,11 @@ import ( "net/url" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/aax/aax_test.go b/adapters/aax/aax_test.go index ad24a2d62e..d1adbcb39f 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/aax/params_test.go b/adapters/aax/params_test.go index 0f93a063e6..8c652e2b4e 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 73a040bbe5..202eb442ba 100644 --- a/adapters/aceex/aceex.go +++ b/adapters/aceex/aceex.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/aceex/aceex_test.go b/adapters/aceex/aceex_test.go index 7aef7dd93f..afa2a81c96 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/aceex/params_test.go b/adapters/aceex/params_test.go index c09e268307..72a4bb238f 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/acuityads/acuityads.go b/adapters/acuityads/acuityads.go index e05ded95e8..4c945d236d 100644 --- a/adapters/acuityads/acuityads.go +++ b/adapters/acuityads/acuityads.go @@ -7,12 +7,13 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/urlutil" ) type AcuityAdsAdapter struct { @@ -107,6 +108,9 @@ func (a *AcuityAdsAdapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.Ext } func (a *AcuityAdsAdapter) buildEndpointURL(params *openrtb_ext.ExtAcuityAds) (string, error) { + if !urlutil.IsSafeHost(params.Host) { + return "", &errortypes.BadInput{Message: "Invalid Host"} + } endpointParams := macros.EndpointTemplateParams{Host: params.Host, AccountID: params.AccountID} return macros.ResolveMacros(a.endpoint, endpointParams) } diff --git a/adapters/acuityads/acuityads_test.go b/adapters/acuityads/acuityads_test.go index b19abd3f7d..0997a6caff 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/acuityads/acuityadstest/supplemental/invalid-host.json b/adapters/acuityads/acuityadstest/supplemental/invalid-host.json new file mode 100644 index 0000000000..c74bf89dc1 --- /dev/null +++ b/adapters/acuityads/acuityadstest/supplemental/invalid-host.json @@ -0,0 +1,30 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "host": "evil.com/path?redirect=http://attacker.com#", + "accountid": "testaccount" + } + } + } + ], + "site": { + "page": "test.com" + } + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Invalid Host", + "comparison": "literal" + } + ] +} diff --git a/adapters/acuityads/params_test.go b/adapters/acuityads/params_test.go index 756dda3ea1..cdd746eff6 100644 --- a/adapters/acuityads/params_test.go +++ b/adapters/acuityads/params_test.go @@ -4,11 +4,16 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ - `{ "host": "ep1", "accountid": "hash" }`, + `{ "host": "host", "accountid": "hash" }`, + `{ "host": "host.example.com", "accountid": "hash" }`, + `{ "host": "host.example.com:8080", "accountid": "hash" }`, + `{ "host": "host-example.test", "accountid": "hash" }`, + `{ "host": "Host.Example.com", "accountid": "hash" }`, + `{ "host": "localhost:3000", "accountid": "hash" }`, } func TestValidParams(t *testing.T) { @@ -35,6 +40,15 @@ var invalidParams = []string{ `{"adCode": "string", "seatCode": 5, "originalPublisherid": "string"}`, `{ "accountid": "hash" }`, `{ "host": "", "accountid": "" }`, + `{ "host": "/path", "accountid": "hash" }`, + `{ "host": "//evil.com", "accountid": "hash" }`, + `{ "host": "host/path", "accountid": "hash" }`, + `{ "host": "host?query=1", "accountid": "hash" }`, + `{ "host": "host#fragment", "accountid": "hash" }`, + `{ "host": "user@host", "accountid": "hash" }`, + `{ "host": "https://host.com", "accountid": "hash" }`, + `{ "host": "host:notaport", "accountid": "hash" }`, + `{ "host": "host:8080:extra", "accountid": "hash" }`, } func TestInvalidParams(t *testing.T) { diff --git a/adapters/adagio/adagio.go b/adapters/adagio/adagio.go index cf5819e978..1d3fd26a06 100644 --- a/adapters/adagio/adagio.go +++ b/adapters/adagio/adagio.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/adagio/adagio_test.go b/adapters/adagio/adagio_test.go index f006fe821d..ef4e28916f 100644 --- a/adapters/adagio/adagio_test.go +++ b/adapters/adagio/adagio_test.go @@ -3,9 +3,9 @@ package adagio 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adagio/params_test.go b/adapters/adagio/params_test.go index e7619b5298..7f974754ec 100644 --- a/adapters/adagio/params_test.go +++ b/adapters/adagio/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adapterstest/adapter_test_util.go b/adapters/adapterstest/adapter_test_util.go index d58437b8fd..7faecb8948 100644 --- a/adapters/adapterstest/adapter_test_util.go +++ b/adapters/adapterstest/adapter_test_util.go @@ -45,21 +45,21 @@ func SampleBid(width *int64, height *int64, impId string, index int) openrtb2.Bi // VerifyStringValue Helper function to assert string equals. func VerifyStringValue(value string, expected string, t *testing.T) { if value != expected { - t.Fatalf(fmt.Sprintf("%s expected, got %s", expected, value)) + t.Fatalf("%s expected, got %s", expected, value) } } // VerifyIntValue Helper function to assert Int equals. func VerifyIntValue(value int, expected int, t *testing.T) { if value != expected { - t.Fatalf(fmt.Sprintf("%d expected, got %d", expected, value)) + t.Fatalf("%d expected, got %d", expected, value) } } // VerifyBoolValue Helper function to assert bool equals. func VerifyBoolValue(value bool, expected bool, t *testing.T) { if value != expected { - t.Fatalf(fmt.Sprintf("%v expected, got %v", expected, value)) + t.Fatalf("%v expected, got %v", expected, value) } } diff --git a/adapters/adapterstest/test_json.go b/adapters/adapterstest/test_json.go index 05312bf29b..911a5b408d 100644 --- a/adapters/adapterstest/test_json.go +++ b/adapters/adapterstest/test_json.go @@ -15,9 +15,9 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "github.com/mitchellh/copystructure" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/adapters" - "github.com/prebid/prebid-server/v3/currency" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/yudai/gojsondiff" "github.com/yudai/gojsondiff/formatter" diff --git a/adapters/adelement/adelement.go b/adapters/adelement/adelement.go index 11b79ad37b..18f9533e95 100644 --- a/adapters/adelement/adelement.go +++ b/adapters/adelement/adelement.go @@ -6,12 +6,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/adelement/adelement_test.go b/adapters/adelement/adelement_test.go index 2cfa599f80..77ee78196b 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adf/adf.go b/adapters/adf/adf.go index 08fb9b8bb4..a75de8f291 100644 --- a/adapters/adf/adf.go +++ b/adapters/adf/adf.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/adf/adf_test.go b/adapters/adf/adf_test.go index 21e8a769c1..e362c600da 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adf/params_test.go b/adapters/adf/params_test.go index 9b3fd7b3e3..f3b4ebfdf5 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 31e27b862a..89492eb7e0 100644 --- a/adapters/adgeneration/adgeneration.go +++ b/adapters/adgeneration/adgeneration.go @@ -10,11 +10,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type AdgenerationAdapter struct { diff --git a/adapters/adgeneration/adgeneration_test.go b/adapters/adgeneration/adgeneration_test.go index e12ed431f0..14161750c7 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adgeneration/params_test.go b/adapters/adgeneration/params_test.go index bdef4ec1d0..b343f079c5 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adhese/adhese.go b/adapters/adhese/adhese.go index 9440a1f580..27dd0140b8 100644 --- a/adapters/adhese/adhese.go +++ b/adapters/adhese/adhese.go @@ -5,12 +5,13 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/urlutil" ) type adapter struct { @@ -66,6 +67,10 @@ func (a *adapter) MakeRequests( modifiedRequest := *request modifiedRequest.Imp[0].Ext = modifiedExt + if !urlutil.IsSafeHost(params.Account) { + return nil, []error{&errortypes.BadInput{Message: "Invalid account"}} + } + // create a map of macros to resolve endpointParams := macros.EndpointTemplateParams{AccountID: params.Account} diff --git a/adapters/adhese/adhese_test.go b/adapters/adhese/adhese_test.go index 66ea75d865..3da9c74f2a 100644 --- a/adapters/adhese/adhese_test.go +++ b/adapters/adhese/adhese_test.go @@ -4,9 +4,9 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" "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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adhese/adhesetest/supplemental/invalid-account.json b/adapters/adhese/adhesetest/supplemental/invalid-account.json new file mode 100644 index 0000000000..f833bf8965 --- /dev/null +++ b/adapters/adhese/adhesetest/supplemental/invalid-account.json @@ -0,0 +1,26 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "account": "evil.com/path?redirect=http://attacker.com#", + "location": "loc1", + "format": "for1" + } + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "Invalid account", + "comparison": "literal" + } + ] +} diff --git a/adapters/adhese/params_test.go b/adapters/adhese/params_test.go index b8ca161d57..5b9ce9e237 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -38,6 +38,11 @@ func TestInvalidParams(t *testing.T) { var validParams = []string{ `{"account": "demo", "location": "loc1", "format": "for1"}`, `{"account": "demo", "location": "loc1", "format": "for1", "targets": { "ab": ["test", "test2"]}}`, + `{"account": "host", "location": "loc1", "format": "for1"}`, + `{"account": "host.example.com", "location": "loc1", "format": "for1"}`, + `{"account": "host-example.test", "location": "loc1", "format": "for1"}`, + `{"account": "Host.Example.com", "location": "loc1", "format": "for1"}`, + `{"account": "localhost", "location": "loc1", "format": "for1"}`, } var invalidParams = []string{ @@ -55,4 +60,14 @@ var invalidParams = []string{ `{"account": "demo", "location": "loc1", "format": 5}`, `{"account": "demo", "location": "loc1", "format": "for1", "targets": "test"}`, `{"account": "demo", "location": "loc1", "format": "for1", "targets": 5}`, + `{"account": "/path", "location": "loc1", "format": "for1"}`, + `{"account": "//evil.com", "location": "loc1", "format": "for1"}`, + `{"account": "host/path", "location": "loc1", "format": "for1"}`, + `{"account": "host?query=1", "location": "loc1", "format": "for1"}`, + `{"account": "host#fragment", "location": "loc1", "format": "for1"}`, + `{"account": "user@host", "location": "loc1", "format": "for1"}`, + `{"account": "https://host.com", "location": "loc1", "format": "for1"}`, + `{"account": "host:notaport", "location": "loc1", "format": "for1"}`, + `{"account": "host:8080:extra", "location": "loc1", "format": "for1"}`, + `{"account": "host:8080", "location": "loc1", "format": "for1"}`, } diff --git a/adapters/adkernel/adkernel.go b/adapters/adkernel/adkernel.go index 443da423fc..d8c6290274 100644 --- a/adapters/adkernel/adkernel.go +++ b/adapters/adkernel/adkernel.go @@ -9,12 +9,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/adapters/adkernel/adkernel_test.go b/adapters/adkernel/adkernel_test.go index f874e92d57..8eb8e6bbfd 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adkernelAdn/adkernelAdn.go b/adapters/adkernelAdn/adkernelAdn.go index ffee88250c..e04d861858 100644 --- a/adapters/adkernelAdn/adkernelAdn.go +++ b/adapters/adkernelAdn/adkernelAdn.go @@ -8,12 +8,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adkernelAdnAdapter struct { diff --git a/adapters/adkernelAdn/adkernelAdn_test.go b/adapters/adkernelAdn/adkernelAdn_test.go index f99da32940..269bea8395 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adman/adman.go b/adapters/adman/adman.go index 8f90a0fe5b..818f38b2ab 100644 --- a/adapters/adman/adman.go +++ b/adapters/adman/adman.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // AdmanAdapter struct diff --git a/adapters/adman/adman_test.go b/adapters/adman/adman_test.go index 1a8eccca62..04a6cea0e0 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adman/params_test.go b/adapters/adman/params_test.go index 97b3d8f3f2..0beac5f516 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 index 435eaba09e..e435a7b72a 100644 --- a/adapters/admatic/admatic.go +++ b/adapters/admatic/admatic.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/admatic/admatic_test.go b/adapters/admatic/admatic_test.go index c98f14e90a..26dd8090d5 100644 --- a/adapters/admatic/admatic_test.go +++ b/adapters/admatic/admatic_test.go @@ -3,9 +3,9 @@ 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/admatic/params_test.go b/adapters/admatic/params_test.go index fc92a1d779..4d656957f7 100644 --- a/adapters/admatic/params_test.go +++ b/adapters/admatic/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/admixer/admixer.go b/adapters/admixer/admixer.go index 726c2cb98c..71765e5a79 100644 --- a/adapters/admixer/admixer.go +++ b/adapters/admixer/admixer.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type AdmixerAdapter struct { diff --git a/adapters/admixer/admixer_test.go b/adapters/admixer/admixer_test.go index 62615a63b3..d092fbfc49 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/admixer/params_test.go b/adapters/admixer/params_test.go index cdc8d56c77..687cceb1b9 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 c1a929a784..f5c55be74e 100644 --- a/adapters/adnuntius/adnuntius.go +++ b/adapters/adnuntius/adnuntius.go @@ -10,12 +10,12 @@ import ( "github.com/buger/jsonparser" "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" - "github.com/prebid/prebid-server/v3/util/timeutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/timeutil" ) const defaultNetwork = "default" @@ -101,8 +101,15 @@ func (a *adapter) generateRequests(ortbRequest openrtb2.BidRequest) ([]*adapters } } + var extUser openrtb_ext.ExtUser + if ortbRequest.User != nil && ortbRequest.User.Ext != nil { + if err := jsonutil.Unmarshal(ortbRequest.User.Ext, &extUser); err != nil { + return nil, []error{fmt.Errorf("failed to parse Ext User: %w", err)} + } + } + + endpoint, err := makeEndpointUrl(ortbRequest, a, noCookies, extUser) - endpoint, err := makeEndpointUrl(ortbRequest, a, noCookies) if err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("failed to parse URL: %s", err), @@ -119,13 +126,6 @@ func (a *adapter) generateRequests(ortbRequest openrtb2.BidRequest) ([]*adapters return nil, []error{fmt.Errorf("failed to parse site Ext: %v", err)} } - var extUser openrtb_ext.ExtUser - if ortbRequest.User != nil && ortbRequest.User.Ext != nil { - if err := jsonutil.Unmarshal(ortbRequest.User.Ext, &extUser); err != nil { - return nil, []error{fmt.Errorf("failed to parse Ext User: %v", err)} - } - } - for _, networkAdunits := range networkAdunitMap { adnuntiusRequest := adnRequest{ @@ -134,13 +134,6 @@ func (a *adapter) generateRequests(ortbRequest openrtb2.BidRequest) ([]*adapters KeyValues: extSite.Data, } - // Will change when our adserver can accept multiple user IDS - if extUser.Eids != nil && len(extUser.Eids) > 0 { - if len(extUser.Eids[0].UIDs) > 0 { - adnuntiusRequest.MetaData.Usi = extUser.Eids[0].UIDs[0].ID - } - } - ortbUser := ortbRequest.User if ortbUser != nil { ortbUserId := ortbRequest.User.ID diff --git a/adapters/adnuntius/adnuntius_test.go b/adapters/adnuntius/adnuntius_test.go index 8b048f7996..b2f78475eb 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adnuntius/adnuntius_types.go b/adapters/adnuntius/adnuntius_types.go index e65a4ddb0b..f218a85e95 100644 --- a/adapters/adnuntius/adnuntius_types.go +++ b/adapters/adnuntius/adnuntius_types.go @@ -3,7 +3,7 @@ package adnuntius import ( "encoding/json" - "github.com/prebid/prebid-server/v3/util/timeutil" + "github.com/prebid/prebid-server/v4/util/timeutil" ) type QueryString map[string]string diff --git a/adapters/adnuntius/adnuntius_utils.go b/adapters/adnuntius/adnuntius_utils.go index 47e25bee6b..4a2d234ba2 100644 --- a/adapters/adnuntius/adnuntius_utils.go +++ b/adapters/adnuntius/adnuntius_utils.go @@ -8,8 +8,8 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type RequestExt struct { @@ -32,7 +32,7 @@ func setHeaders(ortbRequest openrtb2.BidRequest) http.Header { return headers } -func makeEndpointUrl(ortbRequest openrtb2.BidRequest, a *adapter, noCookies bool) (string, []error) { +func makeEndpointUrl(ortbRequest openrtb2.BidRequest, a *adapter, noCookies bool, extUser openrtb_ext.ExtUser) (string, []error) { uri, err := url.Parse(a.endpoint) if err != nil { return "", []error{fmt.Errorf("failed to parse Adnuntius endpoint: %v", err)} @@ -80,6 +80,22 @@ func makeEndpointUrl(ortbRequest openrtb2.BidRequest, a *adapter, noCookies bool q.Set("noCookies", "true") } + if len(extUser.Eids) > 0 { + hasValidEid := false + for _, eid := range extUser.Eids { + if len(eid.UIDs) > 0 { + hasValidEid = true + break + } + } + if hasValidEid { + eidsJSON, err := jsonutil.Marshal(extUser.Eids) + if err == nil { + q.Set("eids", string(eidsJSON)) + } + } + } + q.Set("tzo", strconv.Itoa(tzo)) q.Set("format", "prebidServer") diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-eids-parameter-and-userId.json b/adapters/adnuntius/adnuntiustest/supplemental/check-eids-parameter-and-userId.json new file mode 100644 index 0000000000..2c9e41ae66 --- /dev/null +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-eids-parameter-and-userId.json @@ -0,0 +1,125 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "id": "1kjh3429kjh295jkl", + "ext":{ + "eids" : [ + { + "source": "adserver.org", + "uids": [ + { "id": "111111111111", "atype": 1, "ext": { "rtiPartner": "TDID" } } + ] + }, + { + "source": "pubcid.org", + "uids": [ + { "id": "22222222-2222-2222-2222-222222222222", "atype": 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?eids=%5B%7B%22source%22%3A%22adserver.org%22%2C%22uids%22%3A%5B%7B%22id%22%3A%22111111111111%22%2C%22atype%22%3A1%2C%22ext%22%3A%7B+%22rtiPartner%22%3A+%22TDID%22+%7D%7D%5D%7D%2C%7B%22source%22%3A%22pubcid.org%22%2C%22uids%22%3A%5B%7B%22id%22%3A%2222222222-2222-2222-2222-222222222222%22%2C%22atype%22%3A1%7D%5D%7D%5D&format=prebidServer&tzo=0", + "body": { + "adUnits": [ + { + "auId": "123", + "targetId": "123-test-imp-id:banner", + "nativeRequest": {}, + "dimensions": [[300,250],[300,600]] + } + ], + "metaData": { + "usi": "1kjh3429kjh295jkl" + }, + "context": "unknown" + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "adUnits": [ + { + "auId": "0000000000000123", + "targetId": "123-test-imp-id:banner", + "matchedAdCount": 1, + "html": "", + "responseId": "adn-rsp-900646517", + "ads": [ + { + "destinationUrls": { + "url": "http://www.google.com" + }, + "advertiserDomains": ["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", + "mtype": 1, + "w": 980, + "h": 240 + }, + "type": "banner" + } + ], + "currency": "NOK" + } + ] +} + diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-eids-parameter.json b/adapters/adnuntius/adnuntiustest/supplemental/check-eids-parameter.json new file mode 100644 index 0000000000..484b0637b2 --- /dev/null +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-eids-parameter.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "ext":{ + "eids" : [ + { + "source": "adserver.org", + "uids": [ + { "id": "111111111111", "atype": 1, "ext": { "rtiPartner": "TDID" } } + ] + }, + { + "source": "pubcid.org", + "uids": [ + { "id": "22222222-2222-2222-2222-222222222222", "atype": 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?eids=%5B%7B%22source%22%3A%22adserver.org%22%2C%22uids%22%3A%5B%7B%22id%22%3A%22111111111111%22%2C%22atype%22%3A1%2C%22ext%22%3A%7B+%22rtiPartner%22%3A+%22TDID%22+%7D%7D%5D%7D%2C%7B%22source%22%3A%22pubcid.org%22%2C%22uids%22%3A%5B%7B%22id%22%3A%2222222222-2222-2222-2222-222222222222%22%2C%22atype%22%3A1%7D%5D%7D%5D&format=prebidServer&tzo=0", + "body": { + "adUnits": [ + { + "auId": "123", + "targetId": "123-test-imp-id:banner", + "nativeRequest": {}, + "dimensions": [[300,250],[300,600]] + } + ], + "metaData": {}, + "context": "unknown" + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "adUnits": [ + { + "auId": "0000000000000123", + "targetId": "123-test-imp-id:banner", + "matchedAdCount": 1, + "html": "", + "responseId": "adn-rsp-900646517", + "ads": [ + { + "destinationUrls": { + "url": "http://www.google.com" + }, + "advertiserDomains": ["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", + "mtype": 1, + "w": 980, + "h": 240 + }, + "type": "banner" + } + ], + "currency": "NOK" + } + ] +} + diff --git a/adapters/adnuntius/adnuntiustest/supplemental/user-ext.json b/adapters/adnuntius/adnuntiustest/supplemental/check-empty-eids-parameter.json similarity index 90% rename from adapters/adnuntius/adnuntiustest/supplemental/user-ext.json rename to adapters/adnuntius/adnuntiustest/supplemental/check-empty-eids-parameter.json index 4d3ccb1373..379a77b9f8 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/user-ext.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-empty-eids-parameter.json @@ -4,12 +4,6 @@ "user": { "ext":{ "eids" : [ - { - "source": "idProvider", - "uids": [ - { "id": "userId", "atype": 1, "ext": { "stype": "ppuid" } } - ] - } ] } }, @@ -48,10 +42,8 @@ "nativeRequest": {}, "dimensions": [[300,250],[300,600]] } - ], - "metaData": { - "usi": "userId" - }, + ], + "metaData": {}, "context": "unknown" }, "impIDs":["test-imp-id"] @@ -115,3 +107,4 @@ } ] } + diff --git a/adapters/adnuntius/adnuntiustest/supplemental/user-ext-invalid.json b/adapters/adnuntius/adnuntiustest/supplemental/user-ext-invalid.json index 3e71a4f1ac..1867dd3306 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/user-ext-invalid.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/user-ext-invalid.json @@ -29,7 +29,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "failed to parse URL: [failed to parse GDPR information: failed to parse ExtUser in Adnuntius GDPR check: expect { or n, but found \"]", + "value": "failed to parse Ext User: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adnuntius/params_test.go b/adapters/adnuntius/params_test.go index 92db0b9e5a..9ecae3ef5a 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 deleted file mode 100644 index 82f3200159..0000000000 --- a/adapters/adocean/adocean.go +++ /dev/null @@ -1,408 +0,0 @@ -package adocean - -import ( - "errors" - "fmt" - "math/rand" - "net/http" - "net/url" - "regexp" - "sort" - "strconv" - "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" -) - -const adapterVersion = "1.3.0" -const maxUriLength = 8000 -const measurementCode = ` - -` - -type ResponseAdUnit struct { - ID string `json:"id"` - CrID string `json:"crid"` - Currency string `json:"currency"` - Price string `json:"price"` - Width string `json:"width"` - Height string `json:"height"` - Code string `json:"code"` - WinURL string `json:"winUrl"` - StatsURL string `json:"statsUrl"` - Error string `json:"error"` -} - -type requestData struct { - Url *url.URL - Headers *http.Header - SlaveSizes map[string]string - ImpIDs []string -} - -// Builder builds a new instance of the AdOcean adapter for the given bidder with the given config. -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, errors.New("Unable to parse endpoint template") - } - - whiteSpace := regexp.MustCompile(`\s+`) - - bidder := &AdOceanAdapter{ - endpointTemplate: endpointTemplate, - measurementCode: whiteSpace.ReplaceAllString(measurementCode, " "), - } - return bidder, nil -} - -type AdOceanAdapter struct { - endpointTemplate *template.Template - measurementCode string -} - -func (a *AdOceanAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - if len(request.Imp) == 0 { - return nil, []error{&errortypes.BadInput{ - Message: "No impression in the bid request", - }} - } - - consentString := "" - if request.User != nil { - var extUser openrtb_ext.ExtUser - if err := jsonutil.Unmarshal(request.User.Ext, &extUser); err == nil { - consentString = extUser.Consent - } - } - - var reqCreationErrors []error - var err error - requestsData := make([]*requestData, 0, len(request.Imp)) - for _, auction := range request.Imp { - requestsData, err = a.addNewBid(requestsData, &auction, request, consentString) - if err != nil { - reqCreationErrors = append(reqCreationErrors, err) - } - } - - httpRequests := make([]*adapters.RequestData, 0, len(requestsData)) - for _, requestData := range requestsData { - httpRequests = append(httpRequests, &adapters.RequestData{ - Method: "GET", - Uri: requestData.Url.String(), - Headers: *requestData.Headers, - ImpIDs: requestData.ImpIDs, - }) - } - - return httpRequests, reqCreationErrors -} - -func (a *AdOceanAdapter) addNewBid( - requestsData []*requestData, - imp *openrtb2.Imp, - request *openrtb2.BidRequest, - consentString string, -) ([]*requestData, error) { - var bidderExt adapters.ExtImpBidder - 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 := jsonutil.Unmarshal(bidderExt.Bidder, &adOceanExt); err != nil { - return requestsData, &errortypes.BadInput{ - Message: "Error parsing adOceanExt parameters", - } - } - - if adOceanExt.EmitterPrefix == "" { - return requestsData, &errortypes.BadInput{ - Message: "No emitterPrefix param", - } - } - - addedToExistingRequest := addToExistingRequest(requestsData, &adOceanExt, imp, (request.Test == 1)) - if addedToExistingRequest { - return requestsData, nil - } - - slaveSizes := map[string]string{} - slaveSizes[adOceanExt.SlaveID] = getImpSizes(imp) - - url, err := a.makeURL(&adOceanExt, imp, request, slaveSizes, consentString) - if err != nil { - return requestsData, err - } - - requestsData = append(requestsData, &requestData{ - Url: url, - Headers: a.formHeaders(request), - SlaveSizes: slaveSizes, - ImpIDs: []string{imp.ID}, - }) - - return requestsData, nil -} - -func addToExistingRequest(requestsData []*requestData, newParams *openrtb_ext.ExtImpAdOcean, imp *openrtb2.Imp, testImp bool) bool { - auctionID := imp.ID - - for _, requestData := range requestsData { - queryParams := requestData.Url.Query() - masterID := queryParams["id"][0] - - if masterID == newParams.MasterID { - if _, has := requestData.SlaveSizes[newParams.SlaveID]; has { - continue - } - - queryParams.Add("aid", newParams.SlaveID+":"+auctionID) - requestData.SlaveSizes[newParams.SlaveID] = getImpSizes(imp) - setSlaveSizesParam(&queryParams, requestData.SlaveSizes, testImp) - - newUrl := *(requestData.Url) - newUrl.RawQuery = queryParams.Encode() - if len(newUrl.String()) < maxUriLength { - requestData.Url = &newUrl - requestData.ImpIDs = append(requestData.ImpIDs, auctionID) - return true - } - - delete(requestData.SlaveSizes, newParams.SlaveID) - } - } - - return false -} - -func (a *AdOceanAdapter) makeURL( - params *openrtb_ext.ExtImpAdOcean, - imp *openrtb2.Imp, - request *openrtb2.BidRequest, - slaveSizes map[string]string, - consentString string, -) (*url.URL, error) { - endpointParams := macros.EndpointTemplateParams{Host: params.EmitterPrefix} - host, err := macros.ResolveMacros(a.endpointTemplate, endpointParams) - if err != nil { - return nil, &errortypes.BadInput{ - Message: "Unable to parse endpoint url template: " + err.Error(), - } - } - - endpointURL, err := url.Parse(host) - if err != nil { - return nil, &errortypes.BadInput{ - Message: "Malformed URL: " + err.Error(), - } - } - - randomizedPart := 10000000 + rand.Intn(99999999-10000000) - if request.Test == 1 { - randomizedPart = 10000000 - } - endpointURL.Path = "/_" + strconv.Itoa(randomizedPart) + "/ad.json" - - auctionID := imp.ID - queryParams := url.Values{} - queryParams.Add("pbsrv_v", adapterVersion) - queryParams.Add("id", params.MasterID) - queryParams.Add("nc", "1") - queryParams.Add("nosecure", "1") - queryParams.Add("aid", params.SlaveID+":"+auctionID) - if consentString != "" { - queryParams.Add("gdpr_consent", consentString) - queryParams.Add("gdpr", "1") - } - if request.User != nil && request.User.BuyerUID != "" { - queryParams.Add("hcuserid", request.User.BuyerUID) - } - if request.App != nil { - queryParams.Add("app", "1") - queryParams.Add("appname", request.App.Name) - queryParams.Add("appbundle", request.App.Bundle) - queryParams.Add("appdomain", request.App.Domain) - } - if request.Device != nil { - if request.Device.IFA != "" { - queryParams.Add("ifa", request.Device.IFA) - } else { - queryParams.Add("dpidmd5", request.Device.DPIDMD5) - } - - queryParams.Add("devos", request.Device.OS) - queryParams.Add("devosv", request.Device.OSV) - queryParams.Add("devmodel", request.Device.Model) - queryParams.Add("devmake", request.Device.Make) - } - - setSlaveSizesParam(&queryParams, slaveSizes, (request.Test == 1)) - endpointURL.RawQuery = queryParams.Encode() - - return endpointURL, nil -} - -func (a *AdOceanAdapter) formHeaders(req *openrtb2.BidRequest) *http.Header { - headers := make(http.Header) - headers.Add("Content-Type", "application/json;charset=utf-8") - headers.Add("Accept", "application/json") - - if req.Device != nil { - headers.Add("User-Agent", req.Device.UA) - - if req.Device.IP != "" { - headers.Add("X-Forwarded-For", req.Device.IP) - } else if req.Device.IPv6 != "" { - headers.Add("X-Forwarded-For", req.Device.IPv6) - } - } - - if req.Site != nil { - headers.Add("Referer", req.Site.Page) - } - - return &headers -} - -func getImpSizes(imp *openrtb2.Imp) string { - if imp.Banner == nil { - return "" - } - - if len(imp.Banner.Format) > 0 { - sizes := make([]string, len(imp.Banner.Format)) - for i, format := range imp.Banner.Format { - sizes[i] = strconv.FormatInt(format.W, 10) + "x" + strconv.FormatInt(format.H, 10) - } - - return strings.Join(sizes, "_") - } - - if imp.Banner.W != nil && imp.Banner.H != nil { - return strconv.FormatInt(*imp.Banner.W, 10) + "x" + strconv.FormatInt(*imp.Banner.H, 10) - } - - return "" -} - -func setSlaveSizesParam(queryParams *url.Values, slaveSizes map[string]string, orderByKey bool) { - sizeValues := make([]string, 0, len(slaveSizes)) - slaveIDs := make([]string, 0, len(slaveSizes)) - for k := range slaveSizes { - slaveIDs = append(slaveIDs, k) - } - - if orderByKey { - sort.Strings(slaveIDs) - } - - for _, slaveID := range slaveIDs { - sizes := slaveSizes[slaveID] - if sizes == "" { - continue - } - - rawSlaveID := strings.Replace(slaveID, "adocean", "", 1) - sizeValues = append(sizeValues, rawSlaveID+"~"+sizes) - } - - if len(sizeValues) > 0 { - queryParams.Set("aosspsizes", strings.Join(sizeValues, "-")) - } -} - -func (a *AdOceanAdapter) MakeBids( - internalRequest *openrtb2.BidRequest, - externalRequest *adapters.RequestData, - response *adapters.ResponseData, -) (*adapters.BidderResponse, []error) { - if response.StatusCode != http.StatusOK { - return nil, []error{fmt.Errorf("Unexpected status code: %d. Network error?", response.StatusCode)} - } - - requestURL, _ := url.Parse(externalRequest.Uri) - queryParams := requestURL.Query() - auctionIDs := queryParams["aid"] - - bidResponses := make([]ResponseAdUnit, 0) - if err := jsonutil.Unmarshal(response.Body, &bidResponses); err != nil { - return nil, []error{err} - } - - var parsedResponses = adapters.NewBidderResponseWithBidsCapacity(len(auctionIDs)) - var parsingErrors []error - var slaveToAuctionIDMap = make(map[string]string, len(auctionIDs)) - - for _, auctionFullID := range auctionIDs { - auctionIDsSlice := strings.SplitN(auctionFullID, ":", 2) - slaveToAuctionIDMap[auctionIDsSlice[0]] = auctionIDsSlice[1] - } - - for _, bid := range bidResponses { - if auctionID, found := slaveToAuctionIDMap[bid.ID]; found { - if bid.Error == "true" { - continue - } - - price, _ := strconv.ParseFloat(bid.Price, 64) - width, _ := strconv.ParseInt(bid.Width, 10, 64) - height, _ := strconv.ParseInt(bid.Height, 10, 64) - adCode, err := a.prepareAdCodeForBid(bid) - if err != nil { - parsingErrors = append(parsingErrors, err) - continue - } - - parsedResponses.Bids = append(parsedResponses.Bids, &adapters.TypedBid{ - Bid: &openrtb2.Bid{ - ID: bid.ID, - ImpID: auctionID, - Price: price, - AdM: adCode, - CrID: bid.CrID, - W: width, - H: height, - }, - BidType: openrtb_ext.BidTypeBanner, - }) - parsedResponses.Currency = bid.Currency - } - } - - return parsedResponses, parsingErrors -} - -func (a *AdOceanAdapter) prepareAdCodeForBid(bid ResponseAdUnit) (string, error) { - sspCode, err := url.QueryUnescape(bid.Code) - if err != nil { - return "", err - } - - adCode := fmt.Sprintf(a.measurementCode, bid.WinURL, bid.StatsURL) + sspCode - - return adCode, nil -} diff --git a/adapters/adocean/adocean_test.go b/adapters/adocean/adocean_test.go deleted file mode 100644 index 4fb784bfc0..0000000000 --- a/adapters/adocean/adocean_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package adocean - -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.BidderAdOcean, config.Adapter{ - Endpoint: "https://{{.Host}}.adocean.pl"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "adoceantest", bidder) -} - -func TestEndpointTemplateMalformed(t *testing.T) { - _, buildErr := Builder(openrtb_ext.BidderAdOcean, config.Adapter{ - Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - assert.Error(t, buildErr) -} diff --git a/adapters/adocean/adoceantest/exemplary/multi-banner-impression.json b/adapters/adocean/adoceantest/exemplary/multi-banner-impression.json deleted file mode 100644 index 6eac26e0d0..0000000000 --- a/adapters/adocean/adoceantest/exemplary/multi-banner-impression.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "mockBidRequest": { - "id": "b5300274-a7ec-4cdb-bf5b-d75eeb481a6b", - "source": { - "tid": "b5300274-a7ec-4cdb-bf5b-d75eeb481a6b" - }, - "tmax": 1000, - "imp": [{ - "id": "ao-test", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaozpniqismex" - } - }, - "banner": { - "format": [{ - "w": 300, - "h": 250 - }, { - "w": 320, - "h": 600 - }] - } - }, { - "id": "secod-twelve", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaowafpdwlrks" - } - }, - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - } - }], - "test": 1, - "ext": { - "prebid": { - "targeting": { - "includewinners": true, - "includebidderkeys": false - } - } - }, - "site": { - "publisher": { - "id": "1" - }, - "page": "http://192.168.100.203/testing/prebid_server/test.html" - }, - "device": { - "w": 418, - "h": 961, - "dpidmd5": "f2ba45ece57cff9477d5a8083b138c9g" - }, - "regs": { - "ext": { - "gdpr": 1 - } - }, - "user": { - "ext": { - "consent": "COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw" - } - } - }, - "httpCalls": [{ - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaozpniqismex%3Aao-test&aid=adoceanmyaowafpdwlrks%3Asecod-twelve&aosspsizes=myaowafpdwlrks~300x250-myaozpniqismex~300x250_320x600&devmake=&devmodel=&devos=&devosv=&dpidmd5=f2ba45ece57cff9477d5a8083b138c9g&gdpr=1&gdpr_consent=COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test","secod-twelve"] - }, - "mockResponse": { - "status": 200, - "body": [{ - "id": "adoceanmyaozpniqismex", - "price": "1", - "winurl": "https://win-url.com", - "statsUrl": "https://stats-url.com", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - }, - { - "id": "adoceanmyaowafpdwlrks", - "price": "1", - "winurl": "https://win-url2.com", - "statsUrl": "https://stats-url2.com", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - } - ] - } - }], - "expectedBidResponses": [{ - "currency": "EUR", - "bids": [{ - "bid": { - "id": "adoceanmyaozpniqismex", - "impid": "ao-test", - "price": 1, - "adm": " ", - "crid": "0af345b42983cc4bc0", - "w": 300, - "h": 250 - }, - "type": "banner" - },{ - "bid": { - "id": "adoceanmyaowafpdwlrks", - "impid": "secod-twelve", - "price": 1, - "adm": " ", - "crid": "0af345b42983cc4bc0", - "w": 300, - "h": 250 - }, - "type": "banner" - }] - }] -} diff --git a/adapters/adocean/adoceantest/exemplary/single-banner-impression.json b/adapters/adocean/adoceantest/exemplary/single-banner-impression.json deleted file mode 100644 index 9f5fa2a349..0000000000 --- a/adapters/adocean/adoceantest/exemplary/single-banner-impression.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "mockBidRequest": { - "id": "9ed903f4-383d-406b-8011-4f06526cb02c", - "source": { - "tid": "9ed903f4-383d-406b-8011-4f06526cb02c" - }, - "tmax": 1000, - "imp": [ - { - "id": "ao-test", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaozpniqismex" - } - }, - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "test": 1, - "ext": { - "prebid": { - "targeting": { - "includewinners": true, - "includebidderkeys": false - } - } - }, - "site": { - "publisher": { - "id": "1" - }, - "page": "http://example.com/test.html" - }, - "device": { - "w": 1280, - "h": 720, - "ip": "192.168.1.1", - "ifa": "f2ba45ece57cff9477d5a8083b138c9a" - }, - "regs": { - "ext": { - "gdpr": 1 - } - }, - "user": { - "ext": { - "consent": "COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw" - } - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaozpniqismex%3Aao-test&aosspsizes=myaozpniqismex~300x250&devmake=&devmodel=&devos=&devosv=&gdpr=1&gdpr_consent=COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&ifa=f2ba45ece57cff9477d5a8083b138c9a&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test"] - }, - "mockResponse": { - "status": 200, - "body": [ - { - "id": "adoceanmyaozpniqismex", - "price": "1", - "winurl": "https://win-url.com", - "statsUrl": "https://stats-url.com", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - }, - { - "id": "adoceanmyaowafpdwlrks", - "price": "1", - "winurl": "", - "statsUrl": "", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - } - ] - } - } - ], - "expectedBidResponses": [ - { - "currency": "EUR", - "bids": [ - { - "bid": { - "id": "adoceanmyaozpniqismex", - "impid": "ao-test", - "price": 1, - "adm": " ", - "crid": "0af345b42983cc4bc0", - "w": 300, - "h": 250 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/adocean/adoceantest/supplemental/app.json b/adapters/adocean/adoceantest/supplemental/app.json deleted file mode 100644 index 28c67bdf81..0000000000 --- a/adapters/adocean/adoceantest/supplemental/app.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "mockBidRequest": { - "id": "9ed903f4-383d-406b-8011-4f06526cb02c", - "source": { - "tid": "9ed903f4-383d-406b-8011-4f06526cb02c" - }, - "tmax": 1000, - "imp": [ - { - "id": "ao-test", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaozpniqismex" - } - }, - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "test": 1, - "ext": { - "prebid": { - "targeting": { - "includewinners": true, - "includebidderkeys": false - } - } - }, - "app": { - "id": "ktdf45k34h53k5hjh5k3", - "name": "Weather App", - "cat": ["IAB15","IAB15-10"], - "ver": "1.0.2", - "bundle": "12345", - "domain": "example.com" - }, - "device": { - "w": 1280, - "h": 720, - "ip": "192.168.1.1", - "os": "iOS", - "devicetype": 4, - "ifa": "f2ba45ece57cff9477d5a8083b138c9a" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaozpniqismex%3Aao-test&aosspsizes=myaozpniqismex~300x250&app=1&appbundle=12345&appdomain=example.com&appname=Weather+App&devmake=&devmodel=&devos=iOS&devosv=&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&ifa=f2ba45ece57cff9477d5a8083b138c9a&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test"] - }, - "mockResponse": { - "status": 200, - "body": "{ key: nil }" - } - } - ], - "expectedMakeBidsErrors": [ - { - "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 deleted file mode 100644 index eb1bcb6ef0..0000000000 --- a/adapters/adocean/adoceantest/supplemental/bad-response.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "mockBidRequest": { - "id": "9ed903f4-383d-406b-8011-4f06526cb02c", - "source": { - "tid": "9ed903f4-383d-406b-8011-4f06526cb02c" - }, - "tmax": 1000, - "imp": [ - { - "id": "ao-test", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaozpniqismex" - } - }, - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "test": 1, - "ext": { - "prebid": { - "targeting": { - "includewinners": true, - "includebidderkeys": false - } - } - }, - "site": { - "publisher": { - "id": "1" - }, - "page": "http://example.com/test.html" - }, - "device": { - "w": 1280, - "h": 720, - "ip": "192.168.1.1" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaozpniqismex%3Aao-test&aosspsizes=myaozpniqismex~300x250&devmake=&devmodel=&devos=&devosv=&dpidmd5=&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test"] - }, - "mockResponse": { - "status": 200, - "body": "{ key: nil }" - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "decode slice: expect [ or n, but found \"", - "comparison": "literal" - } - ] -} diff --git a/adapters/adocean/adoceantest/supplemental/emiter-param-error.json b/adapters/adocean/adoceantest/supplemental/emiter-param-error.json deleted file mode 100644 index 154c92e851..0000000000 --- a/adapters/adocean/adoceantest/supplemental/emiter-param-error.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "mockBidRequest": { - "id": "9ed903f4-383d-406b-8011-4f06526cb02c", - "source": { - "tid": "9ed903f4-383d-406b-8011-4f06526cb02c" - }, - "tmax": 1000, - "imp": [ - { - "id": "ao-test", - "ext": { - "bidder": { - "emiter": "myao.adocean.pl", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaozpniqismex" - } - }, - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "test": 1, - "ext": { - "prebid": { - "targeting": { - "includewinners": true, - "includebidderkeys": false - } - } - }, - "site": { - "publisher": { - "id": "1" - }, - "page": "http://example.com/test.html" - }, - "device": { - "w": 1280, - "h": 720, - "ip": "192.168.1.1" - } - }, - "expectedMakeRequestsErrors": [ - { - "value": "No emitterPrefix param", - "comparison": "literal" - } - ] -} diff --git a/adapters/adocean/adoceantest/supplemental/encode-error.json b/adapters/adocean/adoceantest/supplemental/encode-error.json deleted file mode 100644 index 32a0565da2..0000000000 --- a/adapters/adocean/adoceantest/supplemental/encode-error.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "mockBidRequest": { - "id": "9ed903f4-383d-406b-8011-4f06526cb02c", - "source": { - "tid": "9ed903f4-383d-406b-8011-4f06526cb02c" - }, - "tmax": 1000, - "imp": [ - { - "id": "ao-test", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaozpniqismex" - } - }, - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "test": 1, - "ext": { - "prebid": { - "targeting": { - "includewinners": true, - "includebidderkeys": false - } - } - }, - "site": { - "publisher": { - "id": "1" - }, - "page": "http://example.com/test.html" - }, - "device": { - "w": 1280, - "h": 720, - "ip": "192.168.1.1" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaozpniqismex%3Aao-test&aosspsizes=myaozpniqismex~300x250&devmake=&devmodel=&devos=&devosv=&dpidmd5=&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test"] - }, - "mockResponse": { - "status": 200, - "body": [ - { - "id": "adoceanmyaozpniqismex", - "price": "1", - "winurl": "", - "statsUrl": "", - "code": " %a", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - } - ] - } - } - ], - "expectedBidResponses": [{"currency":"USD","bids":[]}], - "expectedMakeBidsErrors": [ - { - "value": "invalid URL escape \"%a\"", - "comparison": "literal" - } - ] -} diff --git a/adapters/adocean/adoceantest/supplemental/network-error.json b/adapters/adocean/adoceantest/supplemental/network-error.json deleted file mode 100644 index 5910a5626b..0000000000 --- a/adapters/adocean/adoceantest/supplemental/network-error.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "mockBidRequest": { - "id": "9ed903f4-383d-406b-8011-4f06526cb02c", - "source": { - "tid": "9ed903f4-383d-406b-8011-4f06526cb02c" - }, - "tmax": 1000, - "imp": [ - { - "id": "ao-test", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaozpniqismex" - } - }, - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "test": 1, - "ext": { - "prebid": { - "targeting": { - "includewinners": true, - "includebidderkeys": false - } - } - }, - "site": { - "publisher": { - "id": "1" - }, - "page": "http://example.com/test.html" - }, - "device": { - "w": 1280, - "h": 720, - "ip": "192.168.1.1" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaozpniqismex%3Aao-test&aosspsizes=myaozpniqismex~300x250&devmake=&devmodel=&devos=&devosv=&dpidmd5=&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test"] - }, - "mockResponse": { - "status": 500, - "body": {} - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "Unexpected status code: 500. Network error?", - "comparison": "literal" - } - ] -} diff --git a/adapters/adocean/adoceantest/supplemental/no-bid.json b/adapters/adocean/adoceantest/supplemental/no-bid.json deleted file mode 100644 index a2c9b9c7ef..0000000000 --- a/adapters/adocean/adoceantest/supplemental/no-bid.json +++ /dev/null @@ -1,161 +0,0 @@ -{ - "mockBidRequest": { - "id": "b5300274-a7ec-4cdb-bf5b-d75eeb481a6b", - "source": { - "tid": "b5300274-a7ec-4cdb-bf5b-d75eeb481a6b" - }, - "tmax": 1000, - "imp": [{ - "id": "ao-test", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaozpniqismex" - } - }, - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - } - }, { - "id": "ao-test-two", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaowafpdwlrks" - } - }, - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - } - }, { - "id": "ao-test-three", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaowafpdwlrks" - } - }, - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - } - }], - "test": 1, - "ext": { - "prebid": { - "targeting": { - "includewinners": true, - "includebidderkeys": false - } - } - }, - "site": { - "publisher": { - "id": "1" - }, - "page": "http://localhost/prebid_server/test.html" - }, - "device": { - "w": 418, - "h": 961 - }, - "regs": { - "ext": { - "gdpr": 1 - } - }, - "user": { - "ext": { - "consent": "COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw" - } - } - }, - "httpCalls": [{ - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaozpniqismex%3Aao-test&aid=adoceanmyaowafpdwlrks%3Aao-test-two&aosspsizes=myaowafpdwlrks~300x250-myaozpniqismex~300x250&devmake=&devmodel=&devos=&devosv=&dpidmd5=&gdpr=1&gdpr_consent=COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test","ao-test-two"] - }, - "mockResponse": { - "status": 200, - "body": [{ - "id": "adoceanmyaozpniqismex", - "error": "true" - }, - { - "id": "adoceanmyaowafpdwlrks", - "price": "1", - "winurl": "https://win-url2.com", - "statsUrl": "https://stats-url2.com", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - } - ] - } - }, { - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaowafpdwlrks%3Aao-test-three&aosspsizes=myaowafpdwlrks~300x250&devmake=&devmodel=&devos=&devosv=&dpidmd5=&gdpr=1&gdpr_consent=COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test-three"] - }, - "mockResponse": { - "status": 200, - "body": [{ - "id": "adoceanmyaowafpdwlrks", - "price": "1", - "winurl": "https://win-url3.com", - "statsUrl": "https://stats-url3.com", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - }] - } - }], - "expectedBidResponses": [{ - "currency": "EUR", - "bids": [{ - "bid": { - "id": "adoceanmyaowafpdwlrks", - "impid": "ao-test-two", - "price": 1, - "adm": " ", - "crid": "0af345b42983cc4bc0", - "w": 300, - "h": 250 - }, - "type": "banner" - }] - }, { - "currency": "EUR", - "bids": [{ - "bid": { - "id": "adoceanmyaowafpdwlrks", - "impid": "ao-test-three", - "price": 1, - "adm": " ", - "crid": "0af345b42983cc4bc0", - "w": 300, - "h": 250 - }, - "type": "banner" - }] - }] -} diff --git a/adapters/adocean/adoceantest/supplemental/no-impression.json b/adapters/adocean/adoceantest/supplemental/no-impression.json deleted file mode 100644 index 8f2a8eef35..0000000000 --- a/adapters/adocean/adoceantest/supplemental/no-impression.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "mockBidRequest": { - "id": "9ed903f4-383d-406b-8011-4f06526cb02c", - "source": { - "tid": "9ed903f4-383d-406b-8011-4f06526cb02c" - }, - "tmax": 1000, - "imp": [], - "test": 1, - "ext": { - "prebid": { - "targeting": { - "includewinners": true, - "includebidderkeys": false - } - } - }, - "site": { - "publisher": { - "id": "1" - }, - "page": "http://example.com/test.html" - }, - "device": { - "w": 1280, - "h": 720, - "ip": "192.168.1.1" - } - }, - "expectedMakeRequestsErrors": [ - { - "value": "No impression in the bid request", - "comparison": "literal" - } - ] -} diff --git a/adapters/adocean/adoceantest/supplemental/no-sizes.json b/adapters/adocean/adoceantest/supplemental/no-sizes.json deleted file mode 100644 index c469f5e095..0000000000 --- a/adapters/adocean/adoceantest/supplemental/no-sizes.json +++ /dev/null @@ -1,170 +0,0 @@ -{ - "mockBidRequest": { - "id": "b5300274-a7ec-4cdb-bf5b-d75eeb481a6b", - "source": { - "tid": "b5300274-a7ec-4cdb-bf5b-d75eeb481a6b" - }, - "tmax": 1000, - "imp": [{ - "id": "ao-test", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaozpniqismex" - } - } - }, { - "id": "ao-test-two", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaowafpdwlrks" - } - }, - "banner": { - "format": [] - } - }, { - "id": "ao-test-three", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaowafpdwlrks" - } - }, - "banner": { - "w": 300, - "h": 250 - } - }], - "test": 1, - "ext": { - "prebid": { - "targeting": { - "includewinners": true, - "includebidderkeys": false - } - } - }, - "site": { - "publisher": { - "id": "1" - }, - "page": "http://localhost/prebid_server/test.html" - }, - "device": { - "w": 418, - "h": 961 - }, - "regs": { - "ext": { - "gdpr": 1 - } - }, - "user": { - "ext": { - "consent": "COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw" - } - } - }, - "httpCalls": [{ - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaozpniqismex%3Aao-test&aid=adoceanmyaowafpdwlrks%3Aao-test-two&devmake=&devmodel=&devos=&devosv=&dpidmd5=&gdpr=1&gdpr_consent=COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test","ao-test-two"] - }, - "mockResponse": { - "status": 200, - "body": [{ - "id": "adoceanmyaozpniqismex", - "price": "1", - "winurl": "https://win-url.com", - "statsUrl": "https://stats-url.com", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - }, - { - "id": "adoceanmyaowafpdwlrks", - "price": "1", - "winurl": "https://win-url2.com", - "statsUrl": "https://stats-url2.com", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - } - ] - } - }, { - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaowafpdwlrks%3Aao-test-three&aosspsizes=myaowafpdwlrks~300x250&devmake=&devmodel=&devos=&devosv=&dpidmd5=&gdpr=1&gdpr_consent=COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test-three"] - }, - "mockResponse": { - "status": 200, - "body": [{ - "id": "adoceanmyaowafpdwlrks", - "price": "1", - "winurl": "https://win-url3.com", - "statsUrl": "https://stats-url3.com", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - }] - } - }], - "expectedBidResponses": [{ - "currency": "EUR", - "bids": [{ - "bid": { - "id": "adoceanmyaozpniqismex", - "impid": "ao-test", - "price": 1, - "adm": " ", - "crid": "0af345b42983cc4bc0", - "w": 300, - "h": 250 - }, - "type": "banner" - }, { - "bid": { - "id": "adoceanmyaowafpdwlrks", - "impid": "ao-test-two", - "price": 1, - "adm": " ", - "crid": "0af345b42983cc4bc0", - "w": 300, - "h": 250 - }, - "type": "banner" - }] - }, { - "currency": "EUR", - "bids": [{ - "bid": { - "id": "adoceanmyaowafpdwlrks", - "impid": "ao-test-three", - "price": 1, - "adm": " ", - "crid": "0af345b42983cc4bc0", - "w": 300, - "h": 250 - }, - "type": "banner" - }] - }] -} diff --git a/adapters/adocean/adoceantest/supplemental/requests-merge.json b/adapters/adocean/adoceantest/supplemental/requests-merge.json deleted file mode 100644 index 240c74bc77..0000000000 --- a/adapters/adocean/adoceantest/supplemental/requests-merge.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "mockBidRequest": { - "id": "b5300274-a7ec-4cdb-bf5b-d75eeb481a6b", - "source": { - "tid": "b5300274-a7ec-4cdb-bf5b-d75eeb481a6b" - }, - "tmax": 1000, - "imp": [{ - "id": "ao-test", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaozpniqismex" - } - }, - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - } - }, { - "id": "ao-test-two", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaowafpdwlrks" - } - }, - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - } - }, { - "id": "ao-test-three", - "ext": { - "bidder": { - "emitterPrefix": "myao", - "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", - "slaveId": "adoceanmyaowafpdwlrks" - } - }, - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - } - }], - "test": 1, - "ext": { - "prebid": { - "targeting": { - "includewinners": true, - "includebidderkeys": false - } - } - }, - "site": { - "publisher": { - "id": "1" - }, - "page": "http://localhost/prebid_server/test.html" - }, - "device": { - "w": 418, - "h": 961 - }, - "regs": { - "ext": { - "gdpr": 1 - } - }, - "user": { - "ext": { - "consent": "COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw" - } - } - }, - "httpCalls": [{ - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaozpniqismex%3Aao-test&aid=adoceanmyaowafpdwlrks%3Aao-test-two&aosspsizes=myaowafpdwlrks~300x250-myaozpniqismex~300x250&devmake=&devmodel=&devos=&devosv=&dpidmd5=&gdpr=1&gdpr_consent=COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test","ao-test-two"] - }, - "mockResponse": { - "status": 200, - "body": [{ - "id": "adoceanmyaozpniqismex", - "price": "1", - "winurl": "https://win-url.com", - "statsUrl": "https://stats-url.com", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - }, - { - "id": "adoceanmyaowafpdwlrks", - "price": "1", - "winurl": "https://win-url2.com", - "statsUrl": "https://stats-url2.com", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - } - ] - } - }, { - "expectedRequest": { - "uri": "https://myao.adocean.pl/_10000000/ad.json?aid=adoceanmyaowafpdwlrks%3Aao-test-three&aosspsizes=myaowafpdwlrks~300x250&devmake=&devmodel=&devos=&devosv=&dpidmd5=&gdpr=1&gdpr_consent=COwK6gaOwK6gaFmAAAENAPCAAAAAAAAAAAAAAAAAAAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&pbsrv_v=1.3.0", - "impIDs":["ao-test-three"] - }, - "mockResponse": { - "status": 200, - "body": [{ - "id": "adoceanmyaowafpdwlrks", - "price": "1", - "winurl": "https://win-url3.com", - "statsUrl": "https://stats-url3.com", - "code": " ", - "currency": "EUR", - "minFloorPrice": "0.01", - "width": "300", - "height": "250", - "crid": "0af345b42983cc4bc0", - "ttl": "300" - }] - } - }], - "expectedBidResponses": [{ - "currency": "EUR", - "bids": [{ - "bid": { - "id": "adoceanmyaozpniqismex", - "impid": "ao-test", - "price": 1, - "adm": " ", - "crid": "0af345b42983cc4bc0", - "w": 300, - "h": 250 - }, - "type": "banner" - }, { - "bid": { - "id": "adoceanmyaowafpdwlrks", - "impid": "ao-test-two", - "price": 1, - "adm": " ", - "crid": "0af345b42983cc4bc0", - "w": 300, - "h": 250 - }, - "type": "banner" - }] - }, { - "currency": "EUR", - "bids": [{ - "bid": { - "id": "adoceanmyaowafpdwlrks", - "impid": "ao-test-three", - "price": 1, - "adm": " ", - "crid": "0af345b42983cc4bc0", - "w": 300, - "h": 250 - }, - "type": "banner" - }] - }] -} diff --git a/adapters/adocean/params_test.go b/adapters/adocean/params_test.go deleted file mode 100644 index 0840d10847..0000000000 --- a/adapters/adocean/params_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package adocean - -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.BidderAdOcean, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected adocean 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.BidderAdOcean, json.RawMessage(invalidParam)); err == nil { - t.Errorf("Schema allowed unexpected params: %s", invalidParam) - } - } -} - -var validParams = []string{ - `{"emitterPrefix": "myao", "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", "slaveId": "adoceanmyaozpniqismex"}`, - `{"emiter": "myao.adocean.pl", "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", "slaveId": "adoceanmyaozpniqismex"}`, -} - -var invalidParams = []string{ - `{}`, - `{"emitterPrefix": "myao", "slaveId": "adoceanmyaozpniqismex"}`, - `{"emitterPrefix": "myao", "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7"}`, - `{"emitterPrefix": "", "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", "slaveId": "adoceanmyaozpniqismex"}`, - `{"emitterPrefix": "myao", "", "slaveId": "adoceanmyaozpniqismex"}`, - `{"emitterPrefix": "myao", "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", "slaveId": ""}`, - `{"emitterPrefix": "myao", "masterId": "tmYF.DMl7Z utQTJfTpxCOmtNPZoQUDcL.G7", "slaveId": "adoceanmyaozpniqismex"}`, - `{"emitterPrefix": "myao", "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", "slaveId": "adoceanmy iqismex"}`, - `{"emitterPrefix": "myao.adocean.pl", "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", "slaveId": "adoceanmyaozpniqismex"}`, - `{"emiter": "myao.adocean.pl", "slaveId": "adoceanmyaozpniqismex"}`, - `{"emiter": "", "masterId": "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7", "slaveId": "adoceanmyaozpniqismex"}`, -} diff --git a/adapters/adoppler/adoppler_test.go b/adapters/adoppler/adoppler_test.go deleted file mode 100644 index 3c6888f312..0000000000 --- a/adapters/adoppler/adoppler_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package adoppler - -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.BidderAdoppler, config.Adapter{ - Endpoint: "http://{{.AccountID}}.trustedmarketplace.com/processHeaderBid/{{.AdUnit}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "adopplertest", bidder) -} diff --git a/adapters/adoppler/adopplertest/exemplary/custom-client.json b/adapters/adoppler/adopplertest/exemplary/custom-client.json deleted file mode 100644 index fe92c36390..0000000000 --- a/adapters/adoppler/adopplertest/exemplary/custom-client.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "mockBidRequest":{ - "id":"req1", - "imp":[ - { - "id":"imp1", - "banner":{ - "w":100, - "h":200 - }, - "ext":{ - "bidder":{ - "adunit":"unit1", - "client":"client1" - } - } - } - ] - }, - "httpCalls":[ - { - "expectedRequest":{ - "uri":"http://client1.trustedmarketplace.com/processHeaderBid/unit1", - "body":{ - "id":"req1-unit1", - "imp":[ - { - "id":"imp1", - "banner":{ - "w":100, - "h":200 - }, - "ext":{ - "bidder":{ - "adunit":"unit1", - "client":"client1" - } - } - } - ] - }, - "impIDs":["imp1"] - }, - "mockResponse":{ - "status":200, - "body":{ - "id":"req1-unit1", - "seatbid":[ - { - "bid":[ - { - "id":"req1-unit1-bid1", - "impid":"imp1", - "price":0.12, - "adm":"An ad" - } - ] - } - ], - "cur":"USD" - } - } - } - ], - "expectedBidResponses":[ - { - "currency":"USD", - "bids":[ - { - "bid":{ - "id":"req1-unit1-bid1", - "impid":"imp1", - "price":0.12, - "adm":"An ad" - }, - "type":"banner" - } - ] - } - ] -} diff --git a/adapters/adot/adot.go b/adapters/adot/adot.go index fc32ef6cae..d0c8d8dd92 100644 --- a/adapters/adot/adot.go +++ b/adapters/adot/adot.go @@ -8,11 +8,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/adot/adot_test.go b/adapters/adot/adot_test.go index d5d5afc6c4..f25379b8d3 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adot/params_test.go b/adapters/adot/params_test.go index 99f8c9d932..2c2b4baa7a 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/adot.json @@ -44,7 +44,6 @@ var validParams = []string{ `{"placementId": "test-113", "parallax": true}`, `{"placementId": "test-113", "parallax": false}`, `{"placementId": "test-113", "parallax": false, "publisherPath": "/hubvisor"}`, - `{"placementId": "test-113", "parallax": false, "publisherPath": ""}`, } var invalidParams = []string{ @@ -55,4 +54,5 @@ var invalidParams = []string{ `{"placementId": 142, "parallax": true}`, `{"placementId": "test-114", "parallax": 1}`, `{"placementId": "test-114", "parallax": true, "publisherPath": 111}`, + `{"placementId": "test-113", "parallax": false, "publisherPath": ""}`, } diff --git a/adapters/adpone/adpone.go b/adapters/adpone/adpone.go index bdf7239889..944238767d 100644 --- a/adapters/adpone/adpone.go +++ b/adapters/adpone/adpone.go @@ -6,12 +6,12 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" - "github.com/prebid/prebid-server/v3/adapters" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // Builder builds a new instance of the Adpone adapter for the given bidder with the given config. diff --git a/adapters/adpone/adpone_test.go b/adapters/adpone/adpone_test.go index e90055b2e6..418574cdcb 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testsDir = "adponetest" diff --git a/adapters/adprime/adprime.go b/adapters/adprime/adprime.go index a4c041ae32..517ddca7a7 100644 --- a/adapters/adprime/adprime.go +++ b/adapters/adprime/adprime.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // AdprimeAdapter struct diff --git a/adapters/adprime/adprime_test.go b/adapters/adprime/adprime_test.go index 0b238b5bee..091c6ee7d2 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adprime/params_test.go b/adapters/adprime/params_test.go index 18556d990e..ea05776e2a 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 4181370005..f730bc9cd7 100644 --- a/adapters/adquery/adquery.go +++ b/adapters/adquery/adquery.go @@ -9,11 +9,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/adapters/adquery/adquery_test.go b/adapters/adquery/adquery_test.go index 913e578195..d06f077729 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adquery/params_test.go b/adapters/adquery/params_test.go index 5619f59cb5..b88b54d8a3 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adquery/types.go b/adapters/adquery/types.go index 62692bb0d0..db173ed408 100644 --- a/adapters/adquery/types.go +++ b/adapters/adquery/types.go @@ -1,6 +1,6 @@ package adquery -import "github.com/prebid/prebid-server/v3/openrtb_ext" +import "github.com/prebid/prebid-server/v4/openrtb_ext" type BidderRequest struct { V string `json:"v"` diff --git a/adapters/adrino/adrino.go b/adapters/adrino/adrino.go index 9139d01789..545956383e 100644 --- a/adapters/adrino/adrino.go +++ b/adapters/adrino/adrino.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/adrino/adrino_test.go b/adapters/adrino/adrino_test.go index 48875bed7c..fe481dc7f9 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adrino/params_test.go b/adapters/adrino/params_test.go index a160113fbd..43d9ae9249 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/adrino.json diff --git a/adapters/ads_interactive/ads_interactive.go b/adapters/ads_interactive/ads_interactive.go deleted file mode 100644 index 5b46ec5248..0000000000 --- a/adapters/ads_interactive/ads_interactive.go +++ /dev/null @@ -1,158 +0,0 @@ -package ads_interactive - -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 { - AdsInteractiveBidderExt 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 - - for _, imp := range request.Imp { - reqCopy := *request - reqCopy.Imp = []openrtb2.Imp{imp} - - var bidderExt adapters.ExtImpBidder - var adsInteractiveExt openrtb_ext.ImpExtAdsInteractive - - if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { - errs = append(errs, err) - continue - } - if err := jsonutil.Unmarshal(bidderExt.Bidder, &adsInteractiveExt); err != nil { - errs = append(errs, err) - continue - } - - impExt := reqBodyExt{AdsInteractiveBidderExt: reqBodyExtBidder{}} - - if adsInteractiveExt.PlacementID != "" { - impExt.AdsInteractiveBidderExt.PlacementID = adsInteractiveExt.PlacementID - impExt.AdsInteractiveBidderExt.Type = "publisher" - } else if adsInteractiveExt.EndpointID != "" { - impExt.AdsInteractiveBidderExt.EndpointID = adsInteractiveExt.EndpointID - impExt.AdsInteractiveBidderExt.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/ads_interactive/ads_interactive_test.go b/adapters/ads_interactive/ads_interactive_test.go deleted file mode 100644 index f8a16d50a1..0000000000 --- a/adapters/ads_interactive/ads_interactive_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package ads_interactive - -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.BidderAdsInteractive, 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, "ads_interactivetest", bidder) -} diff --git a/adapters/ads_interactive/ads_interactivetest/exemplary/endpointId.json b/adapters/ads_interactive/ads_interactivetest/exemplary/endpointId.json deleted file mode 100644 index 14aa475656..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/exemplary/endpointId.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "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": "ads_interactive" - } - ], - "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/ads_interactive/ads_interactivetest/exemplary/multi-format.json b/adapters/ads_interactive/ads_interactivetest/exemplary/multi-format.json deleted file mode 100644 index 9e897a9a1b..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/exemplary/multi-format.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "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/ads_interactive/ads_interactivetest/exemplary/multi-imp.json b/adapters/ads_interactive/ads_interactivetest/exemplary/multi-imp.json deleted file mode 100644 index dbba92907d..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/exemplary/multi-imp.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "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": "ads_interactive" - } - ], - "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": "ads_interactive" - } - ], - "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/ads_interactive/ads_interactivetest/exemplary/simple-banner.json b/adapters/ads_interactive/ads_interactivetest/exemplary/simple-banner.json deleted file mode 100644 index f28f425623..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/exemplary/simple-banner.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "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": "ads_interactive" - } - ], - "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/ads_interactive/ads_interactivetest/exemplary/simple-native.json b/adapters/ads_interactive/ads_interactivetest/exemplary/simple-native.json deleted file mode 100644 index b46c8a3961..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/exemplary/simple-native.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "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": "ads_interactive" - } - ], - "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/ads_interactive/ads_interactivetest/exemplary/simple-video.json b/adapters/ads_interactive/ads_interactivetest/exemplary/simple-video.json deleted file mode 100644 index 8d6475b7b9..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/exemplary/simple-video.json +++ /dev/null @@ -1,131 +0,0 @@ -{ - "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": "ads_interactive" - } - ], - "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/ads_interactive/ads_interactivetest/exemplary/simple-web-banner.json b/adapters/ads_interactive/ads_interactivetest/exemplary/simple-web-banner.json deleted file mode 100644 index 4f973035ed..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/exemplary/simple-web-banner.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "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": "ads_interactive" - } - ], - "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/ads_interactive/ads_interactivetest/supplemental/bad_media_type.json b/adapters/ads_interactive/ads_interactivetest/supplemental/bad_media_type.json deleted file mode 100644 index ca500d19a5..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/supplemental/bad_media_type.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "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": "ads_interactive" - } - ], - "cur": "USD" - } - } - }], - "expectedMakeBidsErrors": [ - { - "value": "could not define media type for impression: test-imp-id", - "comparison": "literal" - } - ] -} diff --git a/adapters/ads_interactive/ads_interactivetest/supplemental/bad_response.json b/adapters/ads_interactive/ads_interactivetest/supplemental/bad_response.json deleted file mode 100644 index 476058ed62..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/supplemental/bad_response.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "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/ads_interactive/ads_interactivetest/supplemental/no-valid-bidder-param.json b/adapters/ads_interactive/ads_interactivetest/supplemental/no-valid-bidder-param.json deleted file mode 100644 index fe0631c032..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/supplemental/no-valid-bidder-param.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "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.ImpExtAdsInteractive.EndpointID: expects \" or n, but found [", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/ads_interactive/ads_interactivetest/supplemental/no-valid-imp-ext.json b/adapters/ads_interactive/ads_interactivetest/supplemental/no-valid-imp-ext.json deleted file mode 100644 index 09108b2d84..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/supplemental/no-valid-imp-ext.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "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/ads_interactive/ads_interactivetest/supplemental/status-204.json b/adapters/ads_interactive/ads_interactivetest/supplemental/status-204.json deleted file mode 100644 index 7dd1c65fd3..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/supplemental/status-204.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "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/ads_interactive/ads_interactivetest/supplemental/status-not-200.json b/adapters/ads_interactive/ads_interactivetest/supplemental/status-not-200.json deleted file mode 100644 index 743f299626..0000000000 --- a/adapters/ads_interactive/ads_interactivetest/supplemental/status-not-200.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "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/ads_interactive/params_test.go b/adapters/ads_interactive/params_test.go deleted file mode 100644 index ec7dc6302e..0000000000 --- a/adapters/ads_interactive/params_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package ads_interactive - -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.BidderAdsInteractive, 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.BidderAdsInteractive, json.RawMessage(p)); err == nil { - t.Errorf("Schema allowed invalid params: %s", p) - } - } -} - -var validParams = []string{ - `{"placementId": "test"}`, - `{"placementId": "1"}`, - `{"endpointId": "test"}`, - `{"endpointId": "1"}`, - `{"placementId": "test", "unknownField": "value"}`, -} - -var invalidParams = []string{ - `{}`, - `{"placementId": 42}`, - `{"endpointId": 42}`, - `{"placementId": "1", "endpointId": "1"}`, - `{"placementId": ""}`, - `{"endpointId": ""}`, - `{"randomField": "value"}`, -} diff --git a/adapters/adsinteractive/adsinteractive.go b/adapters/adsinteractive/adsinteractive.go deleted file mode 100644 index 1969ceb7cc..0000000000 --- a/adapters/adsinteractive/adsinteractive.go +++ /dev/null @@ -1,80 +0,0 @@ -package adsinteractive - -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 -} - -// Builder builds a new instance of the Adsinteractive 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} - } - - requestData := &adapters.RequestData{ - Method: "POST", - Uri: a.endpoint, - Body: requestJSON, - 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 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 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 - for _, seatBid := range response.SeatBid { - for i := range seatBid.Bid { - b := &adapters.TypedBid{ - Bid: &seatBid.Bid[i], - BidType: "banner", - } - bidResponse.Bids = append(bidResponse.Bids, b) - } - } - return bidResponse, nil -} diff --git a/adapters/adsinteractive/adsinteractive_test.go b/adapters/adsinteractive/adsinteractive_test.go deleted file mode 100644 index ae83c615fe..0000000000 --- a/adapters/adsinteractive/adsinteractive_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package adsinteractive - -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" -) - -const testsDir = "adsinteractivetest" -const testsBidderEndpoint = "http://bid.adsinteractive.com/prebid" - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderAdsinteractive, config.Adapter{ - Endpoint: testsBidderEndpoint}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, testsDir, bidder) -} diff --git a/adapters/adsinteractive/params_test.go b/adapters/adsinteractive/params_test.go deleted file mode 100644 index 6b377d6aa3..0000000000 --- a/adapters/adsinteractive/params_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package adsinteractive - -import ( - "encoding/json" - "testing" - - "github.com/prebid/prebid-server/v3/openrtb_ext" -) - -// This file actually intends to test static/bidder-params/adsinteractive.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.BidderAdsinteractive, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected adsinteractive params: %s", validParam) - } - } -} - -// TestInvalidParams makes sure that the Adsinteractive 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.BidderAdsinteractive, json.RawMessage(invalidParam)); err == nil { - t.Errorf("Schema allowed unexpected params: %s", invalidParam) - } - } -} - -var validParams = []string{ - `{"adUnit": "Example_ad_unit_1"}`, -} - -var invalidParams = []string{ - `{"adunit": "Example_ad_unit_1"}`, - `{"AdUnit": "Example_ad_unit_1"}`, - `{"ad_unit": Example_ad_unit_1}`, - ``, - `null`, - `true`, - `[]`, - `{}`, - `nil`, - `53`, - `9.1`, -} diff --git a/adapters/adtarget/adtarget.go b/adapters/adtarget/adtarget.go index c78ffe830f..1e5820d639 100644 --- a/adapters/adtarget/adtarget.go +++ b/adapters/adtarget/adtarget.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type AdtargetAdapter struct { diff --git a/adapters/adtarget/adtarget_test.go b/adapters/adtarget/adtarget_test.go index 23cb51fdfa..57d9f74b96 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adtarget/params_test.go b/adapters/adtarget/params_test.go index cb5a8c9479..aace4e61ad 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/adtarget.json diff --git a/adapters/adtelligent/adtelligent.go b/adapters/adtelligent/adtelligent.go index f56a39736a..b10b35b2f2 100644 --- a/adapters/adtelligent/adtelligent.go +++ b/adapters/adtelligent/adtelligent.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type AdtelligentAdapter struct { diff --git a/adapters/adtelligent/adtelligent_test.go b/adapters/adtelligent/adtelligent_test.go index 64a4573ac1..5e3b8d163f 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adtelligent/params_test.go b/adapters/adtelligent/params_test.go index bd3a2b8583..e9fc435525 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/adtelligent.json diff --git a/adapters/adtonos/adtonos.go b/adapters/adtonos/adtonos.go index e3c20cd932..a15918b99e 100644 --- a/adapters/adtonos/adtonos.go +++ b/adapters/adtonos/adtonos.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/adtonos/adtonos_test.go b/adapters/adtonos/adtonos_test.go index 683ce3e445..ff2709547c 100644 --- a/adapters/adtonos/adtonos_test.go +++ b/adapters/adtonos/adtonos_test.go @@ -3,9 +3,9 @@ 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adtonos/params_test.go b/adapters/adtonos/params_test.go index 703446c9de..b3401fc88a 100644 --- a/adapters/adtonos/params_test.go +++ b/adapters/adtonos/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adtrgtme/adtrgtme.go b/adapters/adtrgtme/adtrgtme.go index a592cfc7c4..977a5a57ad 100644 --- a/adapters/adtrgtme/adtrgtme.go +++ b/adapters/adtrgtme/adtrgtme.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/adtrgtme/adtrgtme_test.go b/adapters/adtrgtme/adtrgtme_test.go index d57b5943af..6d9ae7f5a7 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adtrgtme/params_test.go b/adapters/adtrgtme/params_test.go index 19acaedc88..bedd06ba05 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/aduptech/aduptech.go b/adapters/aduptech/aduptech.go index dee3e679ef..574afe45fd 100644 --- a/adapters/aduptech/aduptech.go +++ b/adapters/aduptech/aduptech.go @@ -7,12 +7,12 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/adapters" - "github.com/prebid/prebid-server/v3/config" - prebidcurrency "github.com/prebid/prebid-server/v3/currency" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + prebidcurrency "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "golang.org/x/text/currency" ) diff --git a/adapters/aduptech/aduptech_test.go b/adapters/aduptech/aduptech_test.go index 64dc6b3d41..26a59c0226 100644 --- a/adapters/aduptech/aduptech_test.go +++ b/adapters/aduptech/aduptech_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "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/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/aduptech/params_test.go b/adapters/aduptech/params_test.go index ce0ae7d126..2899d0ee5f 100644 --- a/adapters/aduptech/params_test.go +++ b/adapters/aduptech/params_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/advangelists/advangelists.go b/adapters/advangelists/advangelists.go index 1d4cd4fb64..677d46e0aa 100644 --- a/adapters/advangelists/advangelists.go +++ b/adapters/advangelists/advangelists.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type AdvangelistsAdapter struct { diff --git a/adapters/advangelists/advangelists_test.go b/adapters/advangelists/advangelists_test.go index 64ae4c89fa..bfebf98c68 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/advangelists/params_test.go b/adapters/advangelists/params_test.go index 8286f7f84a..349f8ea95e 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adverxo/adverxo.go b/adapters/adverxo/adverxo.go index c76038ebde..f0f784d71b 100644 --- a/adapters/adverxo/adverxo.go +++ b/adapters/adverxo/adverxo.go @@ -11,11 +11,11 @@ import ( "github.com/buger/jsonparser" "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type adapter struct { diff --git a/adapters/adverxo/adverxo_test.go b/adapters/adverxo/adverxo_test.go index ca32d50bc3..6194208dd7 100644 --- a/adapters/adverxo/adverxo_test.go +++ b/adapters/adverxo/adverxo_test.go @@ -3,9 +3,9 @@ package adverxo 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adverxo/params_test.go b/adapters/adverxo/params_test.go index a871a03c6e..f18aea3d94 100644 --- a/adapters/adverxo/params_test.go +++ b/adapters/adverxo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adview/adview.go b/adapters/adview/adview.go index 55bf228450..8ea0009d53 100644 --- a/adapters/adview/adview.go +++ b/adapters/adview/adview.go @@ -8,12 +8,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/adview/adview_test.go b/adapters/adview/adview_test.go index 08e824a097..3d9b8a531b 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adview/params_test.go b/adapters/adview/params_test.go index 9dd1c57c2a..748572f1c0 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adxcg/adxcg.go b/adapters/adxcg/adxcg.go index 3b5e290ca3..355b685147 100644 --- a/adapters/adxcg/adxcg.go +++ b/adapters/adxcg/adxcg.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // Builder builds a new instance of the Adxcg adapter for the given bidder with the given config. diff --git a/adapters/adxcg/adxcg_test.go b/adapters/adxcg/adxcg_test.go index 0d94721392..3e21e82941 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testsDir = "adxcgtest" diff --git a/adapters/adyoulike/adyoulike.go b/adapters/adyoulike/adyoulike.go index dbc76f3f75..49118a8068 100644 --- a/adapters/adyoulike/adyoulike.go +++ b/adapters/adyoulike/adyoulike.go @@ -8,11 +8,11 @@ import ( "github.com/buger/jsonparser" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { diff --git a/adapters/adyoulike/adyoulike_test.go b/adapters/adyoulike/adyoulike_test.go index 5a6c91b1c8..80b4d8e9f4 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testsBidderEndpoint = "https://localhost/bid/4" diff --git a/adapters/adyoulike/params_test.go b/adapters/adyoulike/params_test.go index 7c6630fbef..f76a9bf456 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/adyoulike.json diff --git a/adapters/afront/afront.go b/adapters/afront/afront.go index f9c41b6a1b..5d69bd0130 100644 --- a/adapters/afront/afront.go +++ b/adapters/afront/afront.go @@ -6,12 +6,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/afront/afront_test.go b/adapters/afront/afront_test.go index 8a2fde9523..2472f62968 100644 --- a/adapters/afront/afront_test.go +++ b/adapters/afront/afront_test.go @@ -3,9 +3,9 @@ package afront 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/afront/params_test.go b/adapters/afront/params_test.go index b50ff16425..252c8ce043 100644 --- a/adapters/afront/params_test.go +++ b/adapters/afront/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/aidem/aidem.go b/adapters/aidem/aidem.go index 6e8a740959..7486e37981 100644 --- a/adapters/aidem/aidem.go +++ b/adapters/aidem/aidem.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/aidem/aidem_test.go b/adapters/aidem/aidem_test.go index 395bd2ca78..8224cb7a05 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/aidem/params_test.go b/adapters/aidem/params_test.go index bea1d26e3d..933df84581 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 82007b02d0..2ed1306c7b 100644 --- a/adapters/aja/aja.go +++ b/adapters/aja/aja.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type AJAAdapter struct { diff --git a/adapters/aja/aja_test.go b/adapters/aja/aja_test.go index ab4165d09a..6de57ef680 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testsBidderEndpoint = "https://localhost/bid/4" diff --git a/adapters/akcelo/akcelo.go b/adapters/akcelo/akcelo.go index 4abb4c9ef9..78f99bca6c 100644 --- a/adapters/akcelo/akcelo.go +++ b/adapters/akcelo/akcelo.go @@ -5,12 +5,12 @@ import ( "fmt" "github.com/buger/jsonparser" "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" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "net/http" "net/url" ) diff --git a/adapters/akcelo/akcelo_test.go b/adapters/akcelo/akcelo_test.go index a67a31efce..1b2cf90d6d 100644 --- a/adapters/akcelo/akcelo_test.go +++ b/adapters/akcelo/akcelo_test.go @@ -1,9 +1,9 @@ package akcelo import ( - "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/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/require" "testing" ) diff --git a/adapters/akcelo/params_test.go b/adapters/akcelo/params_test.go index 0ff4d9e01f..2b61d9fbf2 100644 --- a/adapters/akcelo/params_test.go +++ b/adapters/akcelo/params_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/algorix/algorix.go b/adapters/algorix/algorix.go index f6848e58e3..2e1ee250b1 100644 --- a/adapters/algorix/algorix.go +++ b/adapters/algorix/algorix.go @@ -8,12 +8,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/algorix/algorix_test.go b/adapters/algorix/algorix_test.go index 6b6d21e4d1..575e7fdef1 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/algorix/params_test.go b/adapters/algorix/params_test.go index 6b5570c9ad..e5d48cfc3d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/alkimi/alkimi.go b/adapters/alkimi/alkimi.go index c85b793315..a207c37ace 100644 --- a/adapters/alkimi/alkimi.go +++ b/adapters/alkimi/alkimi.go @@ -8,14 +8,14 @@ import ( "strconv" "strings" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/floors" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/floors" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const price_macro = "${AUCTION_PRICE}" diff --git a/adapters/alkimi/alkimi_test.go b/adapters/alkimi/alkimi_test.go index 65f296a58e..292f2ea1e4 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/alkimi/params_test.go b/adapters/alkimi/params_test.go index 0ed0be05c6..0d92aab620 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/alliance_gravity/alliance_gravity.go b/adapters/alliance_gravity/alliance_gravity.go new file mode 100644 index 0000000000..73aec9b047 --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravity.go @@ -0,0 +1,181 @@ +package alliance_gravity + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func generateImps(imps []openrtb2.Imp) ([]openrtb2.Imp, error) { + var generatedImps []openrtb2.Imp + for _, imp := range imps { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, &errortypes.BadInput{ + Message: err.Error(), + } + } + + var allianceGravityExt openrtb_ext.ExtImpAllianceGravity + if err := jsonutil.Unmarshal(bidderExt.Bidder, &allianceGravityExt); err != nil { + return nil, &errortypes.BadInput{ + Message: err.Error(), + } + } + + bidderExt.Bidder = json.RawMessage(`{}`) + bidderExt.Prebid = &openrtb_ext.ExtImpPrebid{ + StoredRequest: &openrtb_ext.ExtStoredRequest{ + ID: allianceGravityExt.SrId, + }, + } + + bidderExtJSON, err := jsonutil.Marshal(bidderExt) + if err != nil { + return nil, &errortypes.BadInput{ + Message: err.Error(), + } + } + + impCopy := imp + impCopy.Ext = bidderExtJSON + + generatedImps = append(generatedImps, impCopy) + } + return generatedImps, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var generatedImps, err = generateImps(request.Imp) + if err != nil { + return nil, []error{err} + } + + request.Imp = generatedImps + + requestJSON, err := jsonutil.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") + + if request.Device != nil { + if request.Device.UA != "" { + 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 { + if request.Site.Page != "" { + headers.Add("Referer", request.Site.Page) + } + } + + if request.User != nil && request.User.BuyerUID != "" { + headers.Add("Cookie", "uids="+request.User.BuyerUID) + } + + 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 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 response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + var bids []*adapters.TypedBid + var errors []error + for _, seatBid := range response.SeatBid { + for i, bid := range seatBid.Bid { + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errors = append(errors, err) + continue + } + bids = append(bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + }) + } + } + + if len(bids) == 0 { + return nil, nil + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bids)) + + if response.Cur != "" { + bidResponse.Currency = response.Cur + } + bidResponse.Bids = bids + + return bidResponse, errors +} + +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 impression \"%s\" mediatype", bid.ImpID), + } +} diff --git a/adapters/alliance_gravity/alliance_gravity_test.go b/adapters/alliance_gravity/alliance_gravity_test.go new file mode 100644 index 0000000000..7378ec06d5 --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravity_test.go @@ -0,0 +1,20 @@ +package alliance_gravity + +import ( + "testing" + + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderAllianceGravity, config.Adapter{ + Endpoint: "http://endpoint"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "alliance_gravitytest", bidder) +} diff --git a/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-audio.json b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-audio.json new file mode 100644 index 0000000000..e0aad7ec9d --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-audio.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "audio": { + "mimes": ["audio/mp3"], + "protocols": [2, 5], + "minduration": 10, + "maxduration": 30 + }, + "ext": { + "bidder": { + "srid": "12341234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://endpoint", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Referer": [ + "criteo.com" + ], + "User-Agent": [ + "random user agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "audio": { + "mimes": ["audio/mp3"], + "protocols": [2, 5], + "minduration": 10, + "maxduration": 30 + }, + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "12341234" + } + } + } + } + ] + }, + "impIDs": ["imp-id-123"] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "EUR", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "ext": { + "prebid": { + "type": "audio" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "ext": { + "prebid": { + "type": "audio" + } + } + }, + "type": "audio" + } + ] + } + ] +} + diff --git a/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner-inapp.json b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner-inapp.json new file mode 100755 index 0000000000..7748fbf6f6 --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner-inapp.json @@ -0,0 +1,139 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "srid": "12341234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://endpoint", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "random user agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "12341234" + } + } + } + } + ] + }, + "impIDs": [ + "imp-id-123" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "EUR", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "

test ad

", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "

test ad

", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner-multiple-bids.json b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner-multiple-bids.json new file mode 100644 index 0000000000..db68c93272 --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner-multiple-bids.json @@ -0,0 +1,213 @@ +{ + "mockBidRequest": { + "id": "test-request-id-multiple-bids", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "srid": "abc" + } + } + }, + { + "id": "imp-id-456", + "banner": { + "format": [ + { + "w": 160, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "srid": "def" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://endpoint", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Referer": [ + "criteo.com" + ], + "User-Agent": [ + "random user agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ] + }, + "body": { + "id": "test-request-id-multiple-bids", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "abc" + } + } + } + }, + { + "id": "imp-id-456", + "banner": { + "format": [ + { + "w": 160, + "h": 600 + } + ] + }, + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "def" + } + } + } + } + ] + }, + "impIDs": [ + "imp-id-123", + "imp-id-456" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "EUR", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "
Test Ad
", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + }, + { + "bid": [ + { + "id": "test-slot-id2", + "impid": "imp-id-1232", + "price": 0.5, + "crid": "creative-123", + "adm": "
Test Ad
", + "w": 160, + "h": 600, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "
Test Ad
", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + }, + { + "bid": { + "id": "test-slot-id2", + "impid": "imp-id-1232", + "price": 0.5, + "crid": "creative-123", + "adm": "
Test Ad
", + "w": 160, + "h": 600, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner-with-uid.json b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner-with-uid.json new file mode 100755 index 0000000000..ffee3a656e --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner-with-uid.json @@ -0,0 +1,152 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "user": { + "buyeruid": "grvt-id" + }, + "imp": [ + { + "id": "imp-id-123", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "srid": "12341234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://endpoint", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Referer": [ + "criteo.com" + ], + "User-Agent": [ + "random user agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ], + "Cookie": [ + "uids=grvt-id" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "user": { + "buyeruid": "grvt-id" + }, + "imp": [ + { + "id": "imp-id-123", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "12341234" + } + } + } + } + ] + }, + "impIDs": [ + "imp-id-123" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "EUR", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "test-ad", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "test-ad", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner.json b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner.json new file mode 100644 index 0000000000..55b2dc5183 --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-banner.json @@ -0,0 +1,107 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "imp-id-123", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "srid": "12341234" + } + } + } + ], + "site": {} + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://endpoint", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"imp-id-123", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "12341234" + } + } + } + } + ], + "site": {} + }, + "impIDs":["imp-id-123"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "EUR", + "seatbid": [ + { + "seat": "testalias", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "imp-id-123", + "price": 0.500000, + "adm": "some-banner", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "prebid": { + "type": "banner" + } + } + }] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "imp-id-123", + "price": 0.5, + "adm": "some-banner", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-multi-type-banner.json b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-multi-type-banner.json new file mode 100644 index 0000000000..b51482b54d --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-multi-type-banner.json @@ -0,0 +1,153 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "srid": "12341234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://endpoint", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Referer": [ + "criteo.com" + ], + "User-Agent": [ + "random user agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "12341234" + } + } + } + } + ] + }, + "impIDs":["imp-id-123"] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "EUR", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "

test ad

", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "

test ad

", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-multi-type-video.json b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-multi-type-video.json new file mode 100644 index 0000000000..6b382ede2d --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-multi-type-video.json @@ -0,0 +1,153 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "srid": "12341234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://endpoint", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Referer": [ + "criteo.com" + ], + "User-Agent": [ + "random user agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "12341234" + } + } + } + } + ] + }, + "impIDs":["imp-id-123"] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "EUR", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "video" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} + diff --git a/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-native.json b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-native.json new file mode 100644 index 0000000000..ca9dc94649 --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-native.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id-123", + "native": { + "ver": "1.2", + "request": "{\"ver\":\"1.2\",\"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": { + "srid": "12341234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://endpoint", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Referer": [ + "https://good.site/url" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id-123", + "native": { + "ver": "1.2", + "request": "{\"ver\":\"1.2\",\"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": {}, + "prebid": { + "storedrequest": { + "id": "12341234" + } + } + } + } + ] + }, + "impIDs": [ + "imp-id-123" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "EUR", + "seatbid": [ + { + "seat": "grid", + "bid": [ + { + "id": "randomid", + "impid": "imp-id-123", + "price": 0.5, + "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 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "imp-id-123", + "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" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-video.json b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-video.json new file mode 100644 index 0000000000..cffc45e5f8 --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/exemplary/simple-video.json @@ -0,0 +1,137 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "srid": "12341234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://endpoint", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Referer": [ + "criteo.com" + ], + "User-Agent": [ + "random user agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "1.2.3.4", + "ua": "random user agent" + }, + "imp": [ + { + "id": "imp-id-123", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "12341234" + } + } + } + } + ] + }, + "impIDs":["imp-id-123"] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "EUR", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "video" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "imp-id-123", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} + diff --git a/adapters/screencore/screencoretest/supplemental/invalid-response.json b/adapters/alliance_gravity/alliance_gravitytest/supplemental/204-response.json similarity index 67% rename from adapters/screencore/screencoretest/supplemental/invalid-response.json rename to adapters/alliance_gravity/alliance_gravitytest/supplemental/204-response.json index 79ca5b96dc..b61adcc7a3 100644 --- a/adapters/screencore/screencoretest/supplemental/invalid-response.json +++ b/adapters/alliance_gravity/alliance_gravitytest/supplemental/204-response.json @@ -27,14 +27,18 @@ { "id": "some-impression-id", "tagid": "ogTAGID", - "banner": { - "w": 320, - "h": 50 + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 }, "ext": { "bidder": { - "accountId": "accountId", - "placementId": "placementId" + "srid": "abcdefgh" } } } @@ -44,23 +48,23 @@ { "expectedRequest": { "headers": { - "Content-Type": [ - "application/json;charset=utf-8" - ], "Accept": [ "application/json" ], - "X-Openrtb-Version": [ - "2.5" + "Content-Type": [ + "application/json;charset=utf-8" ], "User-Agent": [ "test-user-agent" ], "X-Forwarded-For": [ "123.123.123.123" + ], + "Cookie": [ + "uids=awesome-user" ] }, - "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "uri": "http://endpoint", "body": { "id": "some-request-id", "device": { @@ -72,11 +76,24 @@ "imp": [ { "id": "some-impression-id", - "banner": { - "w": 320, - "h": 50 + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 }, - "tagid": "ogTAGID" + "tagid": "ogTAGID", + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "abcdefgh" + } + } + } } ], "app": { @@ -96,18 +113,14 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { - "status": 200, - "body": "invalid response" + "status": 204 } } ], - "expectedMakeBidsErrors": [ - { - "value": "Bad Server Response", - "comparison": "literal" - } - ] + "expectedBidResponses": [] } \ No newline at end of file diff --git a/adapters/alliance_gravity/alliance_gravitytest/supplemental/400-response.json b/adapters/alliance_gravity/alliance_gravitytest/supplemental/400-response.json new file mode 100644 index 0000000000..15df859102 --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/supplemental/400-response.json @@ -0,0 +1,132 @@ +{ + "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": { + "srid": "abcdefgh" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ], + "Cookie": [ + "uids=awesome-user" + ] + }, + "uri": "http://endpoint", + "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": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "abcdefgh" + } + } + } + } + ], + "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": 400 + } + } + ], + "expectedBidResponses": [], + "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/alliance_gravity/alliance_gravitytest/supplemental/500-response.json b/adapters/alliance_gravity/alliance_gravitytest/supplemental/500-response.json new file mode 100644 index 0000000000..adde21aeac --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/supplemental/500-response.json @@ -0,0 +1,132 @@ +{ + "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": { + "srid": "abcdefgh" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ], + "Cookie": [ + "uids=awesome-user" + ] + }, + "uri": "http://endpoint", + "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": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "abcdefgh" + } + } + } + } + ], + "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": 500 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info.", + "comparison": "literal" + } + ] +} diff --git a/adapters/screencore/screencoretest/supplemental/empty-seatbid-array.json b/adapters/alliance_gravity/alliance_gravitytest/supplemental/empty_seatbid.json similarity index 80% rename from adapters/screencore/screencoretest/supplemental/empty-seatbid-array.json rename to adapters/alliance_gravity/alliance_gravitytest/supplemental/empty_seatbid.json index 04058fc917..3db49b75d9 100644 --- a/adapters/screencore/screencoretest/supplemental/empty-seatbid-array.json +++ b/adapters/alliance_gravity/alliance_gravitytest/supplemental/empty_seatbid.json @@ -38,8 +38,7 @@ }, "ext": { "bidder": { - "accountId": "accountId", - "placementId": "placementId" + "srid": "abcdefgh" } } } @@ -49,23 +48,23 @@ { "expectedRequest": { "headers": { - "Content-Type": [ - "application/json;charset=utf-8" - ], "Accept": [ "application/json" ], - "X-Openrtb-Version": [ - "2.5" + "Content-Type": [ + "application/json;charset=utf-8" ], "User-Agent": [ "test-user-agent" ], "X-Forwarded-For": [ "123.123.123.123" + ], + "Cookie": [ + "uids=awesome-user" ] }, - "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "uri": "http://endpoint", "body": { "id": "some-request-id", "device": { @@ -86,7 +85,15 @@ "w": 640, "h": 480 }, - "tagid": "ogTAGID" + "tagid": "ogTAGID", + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "abcdefgh" + } + } + } } ], "app": { @@ -106,26 +113,18 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, "body": { - "id": "awesome-resp-id", - "seatbid": [], - "cur": "USD" + "id": "test-request-id", + "seatbid": [] } } } ], - "mockResponse": { - "status": 200, - "body": "invalid response" - }, - "expectedMakeBidsErrors": [ - { - "value": "Empty SeatBid array", - "comparison": "literal" - } - ] + "expectedBidResponses": [] } \ No newline at end of file diff --git a/adapters/alliance_gravity/alliance_gravitytest/supplemental/ext.json b/adapters/alliance_gravity/alliance_gravitytest/supplemental/ext.json new file mode 100644 index 0000000000..6858423661 --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/supplemental/ext.json @@ -0,0 +1,33 @@ +{ + "mockBidRequest": { + "id": "testid", + "imp": [ + { + "id": "testimpid", + "banner": { + "format": [ + { + "w": 320, + "h": 250 + }, + { + "w": 320, + "h": 300 + } + ], + "w": 320, + "h": 250 + }, + "ext": { + "placement_id": "1265" + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "expect { or n, but found", + "comparison": "startswith" + } + ] +} diff --git a/adapters/alliance_gravity/alliance_gravitytest/supplemental/invalid-bid-response.json b/adapters/alliance_gravity/alliance_gravitytest/supplemental/invalid-bid-response.json new file mode 100644 index 0000000000..bb6aeaf44c --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/supplemental/invalid-bid-response.json @@ -0,0 +1,66 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "srid": "1234" + } + } + } + ], + "site": {} + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://endpoint", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "1234" + } + } + } + } + ], + "site": {} + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": {}, + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "cannot unmarshal openrtb2.BidResponse.SeatBid: decode slice: expect [ or n, but found {", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/alliance_gravity/alliance_gravitytest/supplemental/wrong-payload.json b/adapters/alliance_gravity/alliance_gravitytest/supplemental/wrong-payload.json new file mode 100644 index 0000000000..cac99ad7b9 --- /dev/null +++ b/adapters/alliance_gravity/alliance_gravitytest/supplemental/wrong-payload.json @@ -0,0 +1,74 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "srid": "1234" + } + } + } + ], + "site": {} + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://endpoint", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": {}, + "prebid": { + "storedrequest": { + "id": "1234" + } + } + } + } + ], + "site": {} + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "testalias", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-banner", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + } + }] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/intertech/params_test.go b/adapters/alliance_gravity/params_test.go similarity index 59% rename from adapters/intertech/params_test.go rename to adapters/alliance_gravity/params_test.go index eb7bb0aba4..697c99a48f 100644 --- a/adapters/intertech/params_test.go +++ b/adapters/alliance_gravity/params_test.go @@ -1,10 +1,10 @@ -package intertech +package alliance_gravity import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -14,7 +14,7 @@ func TestValidParams(t *testing.T) { } for _, p := range validParams { - if err := validator.Validate(openrtb_ext.BidderIntertech, json.RawMessage(p)); err != nil { + if err := validator.Validate(openrtb_ext.BidderAllianceGravity, json.RawMessage(p)); err != nil { t.Errorf("Schema rejected valid params: %s", p) } } @@ -27,22 +27,22 @@ func TestInvalidParams(t *testing.T) { } for _, p := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderIntertech, json.RawMessage(p)); err == nil { + if err := validator.Validate(openrtb_ext.BidderAllianceGravity, json.RawMessage(p)); err == nil { t.Errorf("Schema allowed invalid params: %s", p) } } } var validParams = []string{ - `{"page_id": 123, "imp_id": 456}`, - `{"page_id": 1, "imp_id": 1}`, - `{"page_id": 999, "imp_id": 999}`, + `{"srid":"11223344"}`, + `{"srid":"1122334455"}`, + `{"srid":"0"}`, + `{"srid":"11223344","other_params":"hoge"}`, } var invalidParams = []string{ - `{"page_id": "abc", "imp_id": 1}`, - `{"page_id": "1", "imp_id": abc}`, - `{"page_id": "123123"}`, - `{"imp_id": "123"}`, `{}`, + `null`, + `12345`, + `{"id":123456}`, } diff --git a/adapters/amx/amx.go b/adapters/amx/amx.go index 38e0f4512e..112717cad0 100644 --- a/adapters/amx/amx.go +++ b/adapters/amx/amx.go @@ -5,17 +5,19 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const nbrHeaderName = "x-nbr" -const adapterVersion = "pbs1.2" +const adapterVersion = "pbs1.3" +const bidderCurrency = "USD" // AMXAdapter is the AMX bid adapter type AMXAdapter struct { @@ -57,12 +59,41 @@ func ensurePublisherWithID(pub *openrtb2.Publisher, publisherID string) openrtb2 return pubCopy } +func resolveBidFloor(imp *openrtb2.Imp, reqInfo *adapters.ExtraRequestInfo) error { + if imp.BidFloor <= 0 || imp.BidFloorCur == "" || strings.EqualFold(imp.BidFloorCur, bidderCurrency) { + return nil + } + + if reqInfo == nil { + return fmt.Errorf("cannot convert bid floor currency %s: reqInfo is nil", imp.BidFloorCur) + } + + convertedValue, err := reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, bidderCurrency) + if err != nil { + return err + } + + imp.BidFloor = convertedValue + imp.BidFloorCur = bidderCurrency + return nil +} + // MakeRequests creates AMX adapter requests func (adapter *AMXAdapter) MakeRequests(request *openrtb2.BidRequest, req *adapters.ExtraRequestInfo) (reqsBidder []*adapters.RequestData, errs []error) { reqCopy := *request var publisherID string - for idx, imp := range reqCopy.Imp { + hasBidFloor := false + validImps := make([]openrtb2.Imp, 0, len(reqCopy.Imp)) + for _, imp := range reqCopy.Imp { + if err := resolveBidFloor(&imp, req); err != nil { + errs = append(errs, err) + continue + } + if imp.BidFloor > 0 { + hasBidFloor = true + } + var params amxExt if err := jsonutil.Unmarshal(imp.Ext, ¶ms); err == nil { if params.Bidder.TagID != "" { @@ -72,9 +103,21 @@ func (adapter *AMXAdapter) MakeRequests(request *openrtb2.BidRequest, req *adapt // if it has an adUnitId, set as the tagid if params.Bidder.AdUnitID != "" { imp.TagID = params.Bidder.AdUnitID - reqCopy.Imp[idx] = imp } } + + validImps = append(validImps, imp) + } + + if len(validImps) == 0 { + return nil, errs + } + reqCopy.Imp = validImps + + // bid floors are normalized to USD, so request USD bids to keep the + // response currency consistent with the floors + if hasBidFloor { + reqCopy.Cur = []string{bidderCurrency} } if publisherID != "" { @@ -147,6 +190,9 @@ func (adapter *AMXAdapter) MakeBids(request *openrtb2.BidRequest, externalReques } bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) + if bidResp.Cur != "" { + bidResponse.Currency = bidResp.Cur + } for _, sb := range bidResp.SeatBid { for _, bid := range sb.Bid { diff --git a/adapters/amx/amx_test.go b/adapters/amx/amx_test.go index 152fcf2b40..e1522a88a1 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/v3/adapters" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" ) const ( diff --git a/adapters/amx/amxtest/exemplary/app-simple.json b/adapters/amx/amxtest/exemplary/app-simple.json index 1bc205e510..81c3216246 100644 --- a/adapters/amx/amxtest/exemplary/app-simple.json +++ b/adapters/amx/amxtest/exemplary/app-simple.json @@ -64,8 +64,11 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", "body": { + "cur": [ + "USD" + ], "app": { "bundle": "639881495", "name": "Imgur (iOS)", diff --git a/adapters/amx/amxtest/exemplary/display-multiple.json b/adapters/amx/amxtest/exemplary/display-multiple.json index 76d97b1704..a14cfcb45c 100644 --- a/adapters/amx/amxtest/exemplary/display-multiple.json +++ b/adapters/amx/amxtest/exemplary/display-multiple.json @@ -98,7 +98,7 @@ }, "httpCalls": [{ "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", "body": { "device": { "dnt": 0, @@ -294,4 +294,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/amx/amxtest/exemplary/simple-native.json b/adapters/amx/amxtest/exemplary/simple-native.json index dc158c1a74..a9b23519fa 100644 --- a/adapters/amx/amxtest/exemplary/simple-native.json +++ b/adapters/amx/amxtest/exemplary/simple-native.json @@ -19,7 +19,7 @@ "httpcalls": [ { "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", "body": { "id": "req_id", "imp": [ diff --git a/adapters/amx/amxtest/exemplary/video-simple.json b/adapters/amx/amxtest/exemplary/video-simple.json index 45e57bf39b..e19a1df15c 100644 --- a/adapters/amx/amxtest/exemplary/video-simple.json +++ b/adapters/amx/amxtest/exemplary/video-simple.json @@ -94,7 +94,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", "body": { "device": { "dnt": 0, diff --git a/adapters/amx/amxtest/exemplary/web-simple.json b/adapters/amx/amxtest/exemplary/web-simple.json index 6067243f12..23d5ccc214 100644 --- a/adapters/amx/amxtest/exemplary/web-simple.json +++ b/adapters/amx/amxtest/exemplary/web-simple.json @@ -98,7 +98,7 @@ }, "httpCalls": [{ "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", "body": { "device": { "dnt": 0, @@ -244,4 +244,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/amx/amxtest/supplemental/204-response.json b/adapters/amx/amxtest/supplemental/204-response.json index cc5eea2416..bdf0d48472 100644 --- a/adapters/amx/amxtest/supplemental/204-response.json +++ b/adapters/amx/amxtest/supplemental/204-response.json @@ -48,7 +48,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", "body": { "device": { "dnt": 0, diff --git a/adapters/amx/amxtest/supplemental/400-response.json b/adapters/amx/amxtest/supplemental/400-response.json index 683bdb8c06..25695233fe 100644 --- a/adapters/amx/amxtest/supplemental/400-response.json +++ b/adapters/amx/amxtest/supplemental/400-response.json @@ -48,7 +48,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", "body": { "device": { "dnt": 0, diff --git a/adapters/amx/amxtest/supplemental/500-response.json b/adapters/amx/amxtest/supplemental/500-response.json index 6beefe80b7..d66466de8d 100644 --- a/adapters/amx/amxtest/supplemental/500-response.json +++ b/adapters/amx/amxtest/supplemental/500-response.json @@ -47,7 +47,7 @@ }, "httpCalls": [{ "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", "body": { "device": { "dnt": 0, diff --git a/adapters/amx/amxtest/supplemental/bid-floor-no-currency.json b/adapters/amx/amxtest/supplemental/bid-floor-no-currency.json new file mode 100644 index 0000000000..33c0bb1dcf --- /dev/null +++ b/adapters/amx/amxtest/supplemental/bid-floor-no-currency.json @@ -0,0 +1,83 @@ +{ + "mockBidRequest": { + "id": "no-floor-currency-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "bidfloor": 1.5, + "ext": { + "bidder": { + "tagId": "cHJlYmlkLm9yZw" + } + } + } + ], + "site": { + "domain": "www.example.com", + "publisher": { + "id": "unused_publisher_id" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", + "body": { + "id": "no-floor-currency-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "bidfloor": 1.5, + "ext": { + "bidder": { + "tagId": "cHJlYmlkLm9yZw" + } + } + } + ], + "site": { + "domain": "www.example.com", + "publisher": { + "id": "cHJlYmlkLm9yZw" + } + } + }, + "impIDs": [ + "1" + ] + }, + "mockResponse": { + "status": 204, + "headers": { + "X-Nbr": ["3b"] + }, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [] +} diff --git a/adapters/amx/amxtest/supplemental/currency-conversion-error.json b/adapters/amx/amxtest/supplemental/currency-conversion-error.json new file mode 100644 index 0000000000..48fc3e5daf --- /dev/null +++ b/adapters/amx/amxtest/supplemental/currency-conversion-error.json @@ -0,0 +1,138 @@ +{ + "mockBidRequest": { + "id": "currency-error-request-id", + "cur": [ + "EUR" + ], + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "bidfloor": 100, + "bidfloorcur": "JPY", + "ext": { + "bidder": { + "tagId": "cHJlYmlkLm9yZw" + } + } + }, + { + "id": "2", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "bidfloor": 1, + "bidfloorcur": "GBP", + "ext": { + "bidder": { + "tagId": "cHJlYmlkLm9yZw" + } + } + } + ], + "site": { + "domain": "www.example.com", + "publisher": { + "id": "unused_publisher_id" + } + }, + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 2 + } + }, + "usepbsrates": false + } + } + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Currency conversion rate not found: 'JPY' => 'USD'", + "comparison": "literal" + } + ], + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", + "body": { + "id": "currency-error-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "id": "2", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "bidfloor": 2, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "tagId": "cHJlYmlkLm9yZw" + } + } + } + ], + "site": { + "domain": "www.example.com", + "publisher": { + "id": "cHJlYmlkLm9yZw" + } + }, + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 2 + } + }, + "usepbsrates": false + } + } + } + }, + "impIDs": [ + "2" + ] + }, + "mockResponse": { + "status": 204, + "headers": { + "X-Nbr": ["3b"] + }, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [] +} diff --git a/adapters/amx/amxtest/supplemental/currency-conversion-no-cur.json b/adapters/amx/amxtest/supplemental/currency-conversion-no-cur.json new file mode 100644 index 0000000000..8b0796817e --- /dev/null +++ b/adapters/amx/amxtest/supplemental/currency-conversion-no-cur.json @@ -0,0 +1,152 @@ +{ + "mockBidRequest": { + "id": "currency-no-cur-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "bidfloor": 1, + "bidfloorcur": "GBP", + "ext": { + "bidder": { + "tagId": "cHJlYmlkLm9yZw" + } + } + } + ], + "site": { + "domain": "www.example.com", + "publisher": { + "id": "unused_publisher_id" + } + }, + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 2 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", + "body": { + "id": "currency-no-cur-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "bidfloor": 2, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "tagId": "cHJlYmlkLm9yZw" + } + } + } + ], + "site": { + "domain": "www.example.com", + "publisher": { + "id": "cHJlYmlkLm9yZw" + } + }, + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 2 + } + }, + "usepbsrates": false + } + } + } + }, + "impIDs": [ + "1" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "currency-no-cur-response-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "TEST", + "impid": "1", + "price": 10, + "adid": "1", + "adm": "", + "adomain": [ + "amxrtb.com" + ], + "cid": "1", + "crid": "1", + "h": 250, + "w": 300 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "TEST", + "impid": "1", + "price": 10, + "adid": "1", + "adm": "", + "adomain": [ + "amxrtb.com" + ], + "cid": "1", + "crid": "1", + "h": 250, + "w": 300 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/amx/amxtest/supplemental/currency-conversion.json b/adapters/amx/amxtest/supplemental/currency-conversion.json new file mode 100644 index 0000000000..2bb59ca963 --- /dev/null +++ b/adapters/amx/amxtest/supplemental/currency-conversion.json @@ -0,0 +1,155 @@ +{ + "mockBidRequest": { + "id": "currency-request-id", + "cur": [ + "EUR" + ], + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "bidfloor": 1, + "bidfloorcur": "GBP", + "ext": { + "bidder": { + "tagId": "cHJlYmlkLm9yZw" + } + } + } + ], + "site": { + "domain": "www.example.com", + "publisher": { + "id": "unused_publisher_id" + } + }, + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 2 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.3", + "body": { + "id": "currency-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "bidfloor": 2, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "tagId": "cHJlYmlkLm9yZw" + } + } + } + ], + "site": { + "domain": "www.example.com", + "publisher": { + "id": "cHJlYmlkLm9yZw" + } + }, + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 2 + } + }, + "usepbsrates": false + } + } + } + }, + "impIDs": [ + "1" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "currency-response-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "TEST", + "impid": "1", + "price": 10, + "adid": "1", + "adm": "", + "adomain": [ + "amxrtb.com" + ], + "cid": "1", + "crid": "1", + "h": 250, + "w": 300 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "TEST", + "impid": "1", + "price": 10, + "adid": "1", + "adm": "", + "adomain": [ + "amxrtb.com" + ], + "cid": "1", + "crid": "1", + "h": 250, + "w": 300 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/amx/params_test.go b/adapters/amx/params_test.go index e44f8a7bbf..9b6f56178d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/apacdex/apacdex.go b/adapters/apacdex/apacdex.go index 698c204e25..fbcff9ee6d 100644 --- a/adapters/apacdex/apacdex.go +++ b/adapters/apacdex/apacdex.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/apacdex/apacdex_test.go b/adapters/apacdex/apacdex_test.go index 4e9e2f4b0e..3fde5068e5 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/apacdex/params_test.go b/adapters/apacdex/params_test.go index ba680ea681..37140f7825 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 a25f3f3164..457ffa642b 100644 --- a/adapters/appnexus/appnexus.go +++ b/adapters/appnexus/appnexus.go @@ -13,15 +13,15 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "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" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/randomutil" + + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/adapters/appnexus/appnexus_test.go b/adapters/appnexus/appnexus_test.go index 63973c6dc3..0772026190 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/adapters/appnexus/params_test.go b/adapters/appnexus/params_test.go index 225b1ac323..6ac1ddc426 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 c78e0b872c..f6fa89e100 100644 --- a/adapters/appush/appush.go +++ b/adapters/appush/appush.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/appush/appush_test.go b/adapters/appush/appush_test.go index 1fe49f87d1..d0c8799436 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/appush/params_test.go b/adapters/appush/params_test.go index b877eb7bfd..21809cd04b 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/aso/aso.go b/adapters/aso/aso.go index 6df776949a..c73616bc91 100644 --- a/adapters/aso/aso.go +++ b/adapters/aso/aso.go @@ -9,12 +9,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/aso/aso_test.go b/adapters/aso/aso_test.go index 41d8e65048..c18ac4efbb 100644 --- a/adapters/aso/aso_test.go +++ b/adapters/aso/aso_test.go @@ -5,9 +5,9 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/aso/params_test.go b/adapters/aso/params_test.go index 4d303220d1..71ba371f54 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded-video-prebid-ext.json b/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded-video-prebid-ext.json new file mode 100644 index 0000000000..b708c8d40d --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded-video-prebid-ext.json @@ -0,0 +1,144 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + }, + "prebid": { + "is_rewarded_inventory": 1 + } + } + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 0, + "h": 0, + "ext": { + "videotype": "rewarded" + } + }, + "rwdd": 1, + "tagid": "123_456" + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [ + { + "bid": [ + { + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":400,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}" + } + ] + } + ], + "bidid": "654", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":400,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987", + "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded-video-rwdd.json b/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded-video-rwdd.json new file mode 100644 index 0000000000..1fcbc2f0a9 --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded-video-rwdd.json @@ -0,0 +1,142 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 940, + "h": 560 + }, + "rwdd": 1, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + } + } + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 0, + "h": 0, + "ext": { + "videotype": "rewarded" + } + }, + "rwdd": 1, + "tagid": "123_456" + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [ + { + "bid": [ + { + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":400,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}" + } + ] + } + ], + "bidid": "654", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":400,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987", + "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded_video_interstitial.json b/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded_video_interstitial.json new file mode 100644 index 0000000000..e6f5fc7d4b --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded_video_interstitial.json @@ -0,0 +1,138 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 940, + "h": 560 + }, + "rwdd": 1, + "instl": 1, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + } + } + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 0, + "h": 0, + "ext": { + "videotype": "rewarded_interstitial" + } + }, + "instl": 1, + "rwdd": 1, + "tagid": "123_456" + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [ + { + "bid": [ + { + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":101,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}" + } + ] + } + ], + "bidid": "654", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":101,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded_video_interstitial_ortb_25.json b/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded_video_interstitial_ortb_25.json new file mode 100644 index 0000000000..670988dd05 --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/exemplary/rewarded_video_interstitial_ortb_25.json @@ -0,0 +1,146 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 940, + "h": 560 + }, + "instl": 1, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + }, + "prebid": { + "is_rewarded_inventory": 1 + } + } + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 0, + "h": 0, + "ext": { + "videotype": "rewarded_interstitial" + } + }, + "instl": 1, + "rwdd": 1, + "tagid": "123_456" + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [ + { + "bid": [ + { + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":400,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}" + } + ] + } + ], + "bidid": "654", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":400,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987", + "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/exemplary/video-interstitial.json b/adapters/audienceNetwork/audienceNetworktest/exemplary/video-interstitial.json new file mode 100644 index 0000000000..fc8d7ab825 --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/exemplary/video-interstitial.json @@ -0,0 +1,134 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 940, + "h": 560 + }, + "instl": 1, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + } + } + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 0, + "h": 0 + }, + "instl": 1, + "tagid": "123_456" + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [ + { + "bid": [ + { + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":101,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}" + } + ] + } + ], + "bidid": "654", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":101,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987", + "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/exemplary/video-non-rewarded.json b/adapters/audienceNetwork/audienceNetworktest/exemplary/video-non-rewarded.json new file mode 100644 index 0000000000..eaf4f614ab --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/exemplary/video-non-rewarded.json @@ -0,0 +1,140 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + }, + "prebid": { + "is_rewarded_inventory": 0 + } + } + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 0, + "h": 0 + }, + "tagid": "123_456" + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [ + { + "bid": [ + { + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}" + } + ] + } + ], + "bidid": "654", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987", + "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0", + "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/supplemental/bid-impid-mismatch.json b/adapters/audienceNetwork/audienceNetworktest/supplemental/bid-impid-mismatch.json new file mode 100644 index 0000000000..c289f8d627 --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/supplemental/bid-impid-mismatch.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + } + } + }], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [{ + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "w": -1, + "h": 250 + }, + "tagid": "123_456" + }], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [{ + "bid": [{ + "id": "987", + "impid": "unknown-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}" + }] + }], + "bidid": "654", + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [] + }], + "expectedMakeBidsErrors": [{ + "value": "bid 987 'impid' unknown-imp-id does not match any imp in the bid request", + "comparison": "literal" + }] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/supplemental/currency-from-response.json b/adapters/audienceNetwork/audienceNetworktest/supplemental/currency-from-response.json new file mode 100644 index 0000000000..17bfbfc021 --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/supplemental/currency-from-response.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + } + } + }], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [{ + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "w": -1, + "h": 250 + }, + "tagid": "123_456" + }], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [{ + "bid": [{ + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}" + }] + }], + "bidid": "654", + "cur": "EUR" + } + } + }], + "expectedBidResponses": [{ + "currency": "EUR", + "bids": [{ + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987" + }, + "type": "banner" + }] + }] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/supplemental/invalid-interstitial.json b/adapters/audienceNetwork/audienceNetworktest/supplemental/invalid-interstitial-native.json similarity index 72% rename from adapters/audienceNetwork/audienceNetworktest/supplemental/invalid-interstitial.json rename to adapters/audienceNetwork/audienceNetworktest/supplemental/invalid-interstitial-native.json index 68ca804481..c23f0cf9c4 100644 --- a/adapters/audienceNetwork/audienceNetworktest/supplemental/invalid-interstitial.json +++ b/adapters/audienceNetwork/audienceNetworktest/supplemental/invalid-interstitial-native.json @@ -3,14 +3,9 @@ "id": "test-req-id", "imp": [{ "id": "test-imp-id", - "video": { - "mimes": ["video/mp4"], - "minduration": 15, - "maxduration": 30, - "protocols": [2, 3, 5, 6, 7, 8], - "linearity": 1, - "w": 940, - "h": 560 + "native": { + "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}}]}", + "ver": "1.1" }, "instl": 1, "ext": { @@ -34,7 +29,7 @@ "tmax": 500 }, "expectedMakeRequestsErrors": [{ - "value": "imp #test-imp-id: interstitial imps are only supported for banner", + "value": "imp #test-imp-id: interstitial imps are only supported for banner and video", "comparison": "literal" }] -} \ No newline at end of file +} diff --git a/adapters/audienceNetwork/audienceNetworktest/supplemental/multi-seat-mixed-bids.json b/adapters/audienceNetwork/audienceNetworktest/supplemental/multi-seat-mixed-bids.json new file mode 100644 index 0000000000..abe8e07fed --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/supplemental/multi-seat-mixed-bids.json @@ -0,0 +1,144 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + } + } + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": -1, + "h": 250 + }, + "tagid": "123_456" + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [ + { + "bid": [ + { + "id": "invalid-bid", + "impid": "test-imp-id", + "price": 0.500000 + } + ] + }, + { + "bid": [ + { + "id": "valid-bid", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"valid-bid\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}" + } + ] + } + ], + "bidid": "654", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "valid-bid", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"valid-bid\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "valid-bid", + "crid": "valid-bid" + }, + "type": "banner" + } + ] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bid invalid-bid missing 'adm'", + "comparison": "literal" + } + ] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-banner-native.json b/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-banner-native.json new file mode 100644 index 0000000000..4990791d1c --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-banner-native.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "native": { + "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + } + } + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "w": -1, + "h": -1 + }, + "tagid": "123_456" + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [ + { + "bid": [ + { + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}" + } + ] + } + ], + "bidid": "654", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987" + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-banner-video.json b/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-banner-video.json new file mode 100644 index 0000000000..f527699c6b --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-banner-video.json @@ -0,0 +1,125 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }], + "w": 300, + "h": 250 + }, + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + } + } + }], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [{ + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [{ + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 0, + "h": 0 + }, + "tagid": "123_456" + }], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [{ + "bid": [{ + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}" + }] + }], + "bidid": "654", + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987" + }, + "type": "video" + }] + }] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-interstitial-banner-video.json b/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-interstitial-banner-video.json new file mode 100644 index 0000000000..57f58b2a0d --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-interstitial-banner-video.json @@ -0,0 +1,140 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 940, + "h": 560 + }, + "instl": 1, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + } + } + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 0, + "h": 0 + }, + "instl": 1, + "tagid": "123_456" + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [ + { + "bid": [ + { + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":101,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}" + } + ] + } + ], + "bidid": "654", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":101,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-interstitial-video-native.json b/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-interstitial-video-native.json new file mode 100644 index 0000000000..596ce2b5cb --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-interstitial-video-native.json @@ -0,0 +1,132 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 940, + "h": 560 + }, + "native": { + "request": "{\"ver\":\"1.1\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}}]}", + "ver": "1.1" + }, + "instl": 1, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + } + } + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 0, + "h": 0 + }, + "instl": 1, + "tagid": "123_456" + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [ + { + "bid": [ + { + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":101,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}" + } + ] + } + ], + "bidid": "654", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":101,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-video-native.json b/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-video-native.json new file mode 100644 index 0000000000..c652bb4edb --- /dev/null +++ b/adapters/audienceNetwork/audienceNetworktest/supplemental/multiformat-video-native.json @@ -0,0 +1,135 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 940, + "h": 560 + }, + "native": { + "request": "{\"ver\":\"1.1\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "publisherid": "123", + "placementid": "456" + } + } + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid" + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500 + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://an.facebook.com/placementbid.ortb", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Fb-Pool-Routing-Token": [ + "v4_bidder_token" + ] + }, + "body": { + "id": "test-imp-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "linearity": 1, + "w": 0, + "h": 0 + }, + "tagid": "123_456" + } + ], + "app": { + "id": "app-abc", + "bundle": "com.prebid", + "publisher": { + "id": "123" + } + }, + "device": { + "ip": "152.193.6.74" + }, + "user": { + "id": "db089de9-a62e-4861-a881-0ff15e052516", + "buyeruid": "v4_bidder_token" + }, + "tmax": 500, + "ext": { + "authentication_id": "4e24a2b23fbfb5e41a9093b921d6cddf497c24dd5f63879038cec2ab2f27d174", + "platformid": "test-platform-id" + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-imp-id", + "seatbid": [ + { + "bid": [ + { + "id": "987", + "impid": "test-imp-id", + "price": 1.000000, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":7,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}" + } + ] + } + ], + "bidid": "654", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "987", + "impid": "test-imp-id", + "price": 1, + "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":7,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}", + "adid": "987", + "crid": "987" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/audienceNetwork/facebook.go b/adapters/audienceNetwork/facebook.go index 50804a862b..14316d27dd 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/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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/maputil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) var supportedBannerHeights = map[int64]struct{}{ @@ -175,6 +175,40 @@ func (a *adapter) modifyRequest(out *openrtb2.BidRequest) error { return err } + // Preserve rewarded signal before clearing ext. For ORTB 2.5 adapters, + // PBS moves imp.rwdd to imp.ext.prebid.is_rewarded_inventory via ConvertDownTo25. + // Since we clear imp.Ext below, the signal would be lost. Extract it now and + // restore it on the struct field so it serializes as imp.rwdd for Meta. + if imp.Rwdd != 1 && imp.Ext != nil { + if val, err := jsonparser.GetInt(imp.Ext, "prebid", "is_rewarded_inventory"); err == nil && val == 1 { + imp.Rwdd = 1 + } + } + if imp.Rwdd == 1 && imp.Video != nil { + videoCopy := *imp.Video + var extMap map[string]interface{} + if videoCopy.Ext != nil { + if err := jsonutil.Unmarshal(videoCopy.Ext, &extMap); err != nil { + return err + } + } else { + extMap = make(map[string]interface{}) + } + // Derive videotype from standard OpenRTB signals. Meta documents + // "rewarded" and "rewarded_interstitial" as distinct rewarded videotypes. + // Use instl to distinguish: rwdd+instl → rewarded_interstitial, rwdd alone → rewarded. + if imp.Instl == 1 { + extMap["videotype"] = "rewarded_interstitial" + } else { + extMap["videotype"] = "rewarded" + } + videoCopy.Ext, err = jsonutil.Marshal(extMap) + if err != nil { + return err + } + imp.Video = &videoCopy + } + imp.TagID = pubId + "_" + plmtId imp.Ext = nil @@ -196,12 +230,38 @@ func (a *adapter) modifyRequest(out *openrtb2.BidRequest) error { func modifyImp(out *openrtb2.Imp) error { impType := resolveImpType(out) - if out.Instl == 1 && impType != openrtb_ext.BidTypeBanner { + if out.Instl == 1 && !isValidInterstitial(impType) { return &errortypes.BadInput{ - Message: fmt.Sprintf("imp #%s: interstitial imps are only supported for banner", out.ID), + Message: fmt.Sprintf("imp #%s: interstitial imps are only supported for banner and video", out.ID), } } + // Meta's only non-rewarded interstitial request shape is banner{0,0}+instl:1, which + // renders display or video client-side (per Meta's Audience Network server-to-server + // spec). Map a non-rewarded video interstitial to that shape instead of rejecting it. + // Rewarded video interstitials keep their video imp so Meta receives videotype "rewarded_interstitial". + if out.Instl == 1 && impType == openrtb_ext.BidTypeVideo && out.Rwdd != 1 { + out.Banner = &openrtb2.Banner{} + impType = openrtb_ext.BidTypeBanner + } + + // Audience Network placements are single-format, so send Meta only the resolved + // media object and drop any other media carried by a multi-format impression. + switch impType { + case openrtb_ext.BidTypeBanner: + out.Video = nil + out.Audio = nil + out.Native = nil + case openrtb_ext.BidTypeVideo: + out.Banner = nil + out.Audio = nil + out.Native = nil + case openrtb_ext.BidTypeNative: + out.Banner = nil + out.Video = nil + out.Audio = nil + } + if impType == openrtb_ext.BidTypeBanner { bannerCopy := *out.Banner out.Banner = &bannerCopy @@ -241,6 +301,10 @@ func modifyImp(out *openrtb2.Imp) error { return nil } +func isValidInterstitial(impType openrtb_ext.BidType) bool { + return impType == openrtb_ext.BidTypeBanner || impType == openrtb_ext.BidTypeVideo +} + func extractPlacementAndPublisher(out *openrtb2.Imp) (string, string, error) { var bidderExt adapters.ExtImpBidder if err := jsonutil.Unmarshal(out.Ext, &bidderExt); err != nil { @@ -329,7 +393,7 @@ func modifyImpCustom(jsonData []byte, imp *openrtb2.Imp) ([]byte, error) { case openrtb_ext.BidTypeNative: nativeMap, ok := maputil.ReadEmbeddedMap(impMap, "native") if !ok { - return jsonData, errors.New("unable to find imp[0].video in json data") + return jsonData, errors.New("unable to find imp[0].native in json data") } // Set w/h to -1 for native impressions based on the facebook native spec. @@ -370,6 +434,9 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, adapterRequest *adapter } out := adapters.NewBidderResponseWithBidsCapacity(4) + if bidResp.Cur != "" { + out.Currency = bidResp.Cur + } var errs []error for _, seatbid := range bidResp.SeatBid { @@ -413,9 +480,15 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, adapterRequest *adapter bid.AdID = obj.BidID bid.CrID = obj.BidID + bidType, err := resolveBidType(&bid, request) + if err != nil { + errs = append(errs, err) + continue + } + out.Bids = append(out.Bids, &adapters.TypedBid{ Bid: &bid, - BidType: resolveBidType(&bid, request), + BidType: bidType, }) } } @@ -423,33 +496,56 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, adapterRequest *adapter return out, errs } -func resolveBidType(bid *openrtb2.Bid, req *openrtb2.BidRequest) openrtb_ext.BidType { +// resolveBidType reports a bid's media type from the ORIGINAL request imp it fills, +// not from the Meta-facing transformed copy. This is deliberate: a non-rewarded +// video interstitial is sent to Meta as banner{0,0}+instl (see modifyImp), but the +// bid still fills the publisher's video interstitial slot, so it is reported as +// video. Meta's interstitial creative is a deferred token whose display-vs-video +// form is resolved client-side at render — the bid carries no media type — so the +// slot type is the most specific media classification the adapter can assert, and +// bid.MType is intentionally left unset rather than claiming an unverifiable form. +func resolveBidType(bid *openrtb2.Bid, req *openrtb2.BidRequest) (openrtb_ext.BidType, error) { for _, imp := range req.Imp { if bid.ImpID == imp.ID { - return resolveImpType(&imp) + return resolveImpType(&imp), nil } } - panic(fmt.Sprintf("Invalid bid imp ID %s does not match any imp IDs from the original bid request", bid.ImpID)) + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("bid %s 'impid' %s does not match any imp in the bid request", bid.ID, bid.ImpID), + } } func resolveImpType(imp *openrtb2.Imp) openrtb_ext.BidType { - if imp.Banner != nil { - return openrtb_ext.BidTypeBanner + // Preserve interstitial semantics before applying the general expected-yield + // priority. Meta accepts banner and video interstitials, but not native or audio. + if imp.Instl == 1 { + if imp.Video != nil { + return openrtb_ext.BidTypeVideo + } + if imp.Banner != nil { + return openrtb_ext.BidTypeBanner + } } + // Audience Network placements are single-format. For an ordinary multi-format + // impression, prefer the formats with the highest likely yield. if imp.Video != nil { return openrtb_ext.BidTypeVideo } - if imp.Audio != nil { - return openrtb_ext.BidTypeAudio - } - if imp.Native != nil { return openrtb_ext.BidTypeNative } + if imp.Banner != nil { + return openrtb_ext.BidTypeBanner + } + + if imp.Audio != nil { + return openrtb_ext.BidTypeAudio + } + // Required to satisfy compiler. Not reachable in practice due to validations performed in PBS-Core. return openrtb_ext.BidTypeBanner } diff --git a/adapters/audienceNetwork/facebook_test.go b/adapters/audienceNetwork/facebook_test.go index 6fdc121f94..ed1a1866fa 100644 --- a/adapters/audienceNetwork/facebook_test.go +++ b/adapters/audienceNetwork/facebook_test.go @@ -4,10 +4,11 @@ import ( "testing" "time" - "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/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -55,6 +56,51 @@ func TestJsonSamples(t *testing.T) { adapterstest.RunJSONBidderTest(t, "audienceNetworktest", bidder) } +func TestResolveImpTypePriority(t *testing.T) { + tests := []struct { + name string + imp openrtb2.Imp + expected openrtb_ext.BidType + }{ + { + name: "video over banner", + imp: openrtb2.Imp{Banner: &openrtb2.Banner{}, Video: &openrtb2.Video{}}, + expected: openrtb_ext.BidTypeVideo, + }, + { + name: "native over banner", + imp: openrtb2.Imp{Banner: &openrtb2.Banner{}, Native: &openrtb2.Native{}}, + expected: openrtb_ext.BidTypeNative, + }, + { + name: "video over native and banner", + imp: openrtb2.Imp{Banner: &openrtb2.Banner{}, Video: &openrtb2.Video{}, Native: &openrtb2.Native{}}, + expected: openrtb_ext.BidTypeVideo, + }, + { + name: "interstitial banner over unsupported native", + imp: openrtb2.Imp{Banner: &openrtb2.Banner{}, Native: &openrtb2.Native{}, Instl: 1}, + expected: openrtb_ext.BidTypeBanner, + }, + { + name: "interstitial video over native", + imp: openrtb2.Imp{Video: &openrtb2.Video{}, Native: &openrtb2.Native{}, Instl: 1}, + expected: openrtb_ext.BidTypeVideo, + }, + { + name: "banner over unsupported audio", + imp: openrtb2.Imp{Banner: &openrtb2.Banner{}, Audio: &openrtb2.Audio{}}, + expected: openrtb_ext.BidTypeBanner, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.expected, resolveImpType(&test.imp)) + }) + } +} + func TestMakeTimeoutNoticeApp(t *testing.T) { req := adapters.RequestData{ Body: []byte(`{"id":"1234","imp":[{"id":"1234"}],"app":{"publisher":{"id":"5678"}}}`), diff --git a/adapters/automatad/automatad.go b/adapters/automatad/automatad.go index cfe5f5089b..6ce0602fb7 100644 --- a/adapters/automatad/automatad.go +++ b/adapters/automatad/automatad.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/automatad/automatad_test.go b/adapters/automatad/automatad_test.go index 515025c862..faa3431e8e 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/automatad/params_test.go b/adapters/automatad/params_test.go index 7f8d6e789e..ec3a42e5fd 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/avocet/avocet.go b/adapters/avocet/avocet.go index 8bf2b7d89a..a18bc4ed9e 100644 --- a/adapters/avocet/avocet.go +++ b/adapters/avocet/avocet.go @@ -7,11 +7,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // AvocetAdapter implements a adapters.Bidder compatible with the Avocet advertising platform. diff --git a/adapters/avocet/avocet_test.go b/adapters/avocet/avocet_test.go index 082a7c1ee6..42a417acaa 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/axis/axis.go b/adapters/axis/axis.go index d28eca6a8a..3f104c75e7 100644 --- a/adapters/axis/axis.go +++ b/adapters/axis/axis.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/axis/axis_test.go b/adapters/axis/axis_test.go index 24048f1856..42481f0e40 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/axis/params_test.go b/adapters/axis/params_test.go index ad5cec52fd..aa5b82f5d9 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/axonix/axonix.go b/adapters/axonix/axonix.go index 81e5937a14..33b19e14f8 100644 --- a/adapters/axonix/axonix.go +++ b/adapters/axonix/axonix.go @@ -10,12 +10,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/axonix/axonix_test.go b/adapters/axonix/axonix_test.go index 1d398c5351..73ac0d981d 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/axonix/params_test.go b/adapters/axonix/params_test.go index b839bcb20f..645a72338d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 8e293837f1..869451c98e 100644 --- a/adapters/beachfront/beachfront.go +++ b/adapters/beachfront/beachfront.go @@ -10,12 +10,12 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) const Seat = "beachfront" diff --git a/adapters/beachfront/beachfront_test.go b/adapters/beachfront/beachfront_test.go index 304747503f..b2beadce3f 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/beachfront/params_test.go b/adapters/beachfront/params_test.go index 3bfbeba635..13e341b5b7 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/beintoo/beintoo.go b/adapters/beintoo/beintoo.go index 18290e6df4..a76d57966c 100644 --- a/adapters/beintoo/beintoo.go +++ b/adapters/beintoo/beintoo.go @@ -8,11 +8,11 @@ import ( "strconv" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type BeintooAdapter struct { diff --git a/adapters/beintoo/beintoo_test.go b/adapters/beintoo/beintoo_test.go index 8dfb257b3d..d6ca33bf19 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/beintoo/params_test.go b/adapters/beintoo/params_test.go index 211912a8cb..f9c4e8f344 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bematterfull/bematterfull.go b/adapters/bematterfull/bematterfull.go index 89b984c5eb..3c9c16d6b3 100644 --- a/adapters/bematterfull/bematterfull.go +++ b/adapters/bematterfull/bematterfull.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type bidType struct { diff --git a/adapters/bematterfull/bematterfulltest_test.go b/adapters/bematterfull/bematterfulltest_test.go index 92296231b0..9789cccae0 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/bematterfull/params_test.go b/adapters/bematterfull/params_test.go index 769195f6f0..bd7478c4e5 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/beop/beop.go b/adapters/beop/beop.go new file mode 100644 index 0000000000..bb4f862a5d --- /dev/null +++ b/adapters/beop/beop.go @@ -0,0 +1,172 @@ +package beop + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +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) getRequestExtImpBeop(imp *openrtb2.Imp) (*openrtb_ext.ExtImpBeop, error) { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "ext.bidder not provided", + } + } + var beopExt openrtb_ext.ExtImpBeop + if err := jsonutil.Unmarshal(bidderExt.Bidder, &beopExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "ext.bidder not provided", + } + } + return &beopExt, nil +} + +func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtImpBeop) (string, error) { + url, _ := url.Parse(a.endpoint) + query := url.Query() + if pid := params.BeopPublisherID; len(pid) != 0 { + query.Set("pid", pid) + } + if nid := params.BeopNetworkID; len(nid) != 0 { + query.Set("nid", nid) + } + if nptnid := params.BeopNetworkPartnerID; len(nptnid) != 0 { + query.Set("nptnid", nptnid) + } + url.RawQuery = query.Encode() + return url.String(), nil +} + +func (a *adapter) MakeRequests( + request *openrtb2.BidRequest, + requestInfo *adapters.ExtraRequestInfo) ( + []*adapters.RequestData, []error, +) { + var beopExt *openrtb_ext.ExtImpBeop + var err error + + beopExt, err = a.getRequestExtImpBeop(&request.Imp[0]) + 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") + + url, err := a.buildEndpointURL(beopExt) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: url, + Body: requestJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + } + + return []*adapters.RequestData{requestData}, nil +} + +func getMediaTypeForBid(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { + mType := bid.MType + var bidType openrtb_ext.BidType + switch mType { + case openrtb2.MarkupBanner: + bidType = openrtb_ext.BidTypeBanner + case openrtb2.MarkupVideo: + bidType = openrtb_ext.BidTypeVideo + default: + return bidType, fmt.Errorf("Failed to parse bid mType for impression \"%s\"", bid.ImpID) + } + return bidType, nil +} + +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.StatusServiceUnavailable { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Service Unavailable. Status Code: [ %d ] ", responseData.StatusCode), + }} + } + + if responseData.StatusCode == http.StatusBadRequest { + 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 responseBody openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &responseBody); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Bad Server Response", + }} + } + + if len(responseBody.SeatBid) == 0 { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Empty SeatBid array", + }} + } + + bidResponseFinal := adapters.NewBidderResponseWithBidsCapacity(len(responseBody.SeatBid[0].Bid)) + seatBid := responseBody.SeatBid[0] + var errors []error + for i := range seatBid.Bid { + bid := &seatBid.Bid[i] + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errors = append(errors, err) + continue + } + bidResponseFinal.Bids = append(bidResponseFinal.Bids, &adapters.TypedBid{ + Bid: bid, + BidType: bidType, + }) + } + if len(bidResponseFinal.Bids) == 0 { + return nil, errors + } + return bidResponseFinal, errors +} diff --git a/adapters/beop/beop_test.go b/adapters/beop/beop_test.go new file mode 100644 index 0000000000..4be3022496 --- /dev/null +++ b/adapters/beop/beop_test.go @@ -0,0 +1,21 @@ +package beop + +import ( + "testing" + + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderBeop, config.Adapter{ + Endpoint: "http://hb-test.collectiveaudience.co/rtb/bid"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "beoptest", bidder) +} diff --git a/adapters/beop/beoptest/exemplary/banner-web-with-nid.json b/adapters/beop/beoptest/exemplary/banner-web-with-nid.json new file mode 100644 index 0000000000..e0c6f9a880 --- /dev/null +++ b/adapters/beop/beoptest/exemplary/banner-web-with-nid.json @@ -0,0 +1,155 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "tmax": 1000, + "user": { + "id": "some-user" + }, + "imp": [ + { + "id": "impression-id", + "tagid": "tid", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "nid": "aaaaaaaaaaaaaaaaaaaaaaaa", + "nptnid": "1234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "uri": "http://hb-test.collectiveaudience.co/rtb/bid?nid=aaaaaaaaaaaaaaaaaaaaaaaa&nptnid=1234", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "request-id", + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "imp": [ + { + "id": "impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "tid", + "ext": { + "bidder": { + "nid": "aaaaaaaaaaaaaaaaaaaaaaaa", + "nptnid": "1234" + } + } + } + ], + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "id": "some-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "123456789", + "impid": "impression-id", + "price": 2, + "adm": "adm code", + "adomain": [ + "testdomain.com" + ], + "crid": "100", + "w": 320, + "h": 50, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "123456789", + "impid": "impression-id", + "price": 2, + "adm": "adm code", + "adomain": [ + "testdomain.com" + ], + "crid": "100", + "w": 320, + "h": 50, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/beop/beoptest/exemplary/banner-web.json b/adapters/beop/beoptest/exemplary/banner-web.json new file mode 100644 index 0000000000..a757171e34 --- /dev/null +++ b/adapters/beop/beoptest/exemplary/banner-web.json @@ -0,0 +1,153 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "tmax": 1000, + "user": { + "id": "some-user" + }, + "imp": [ + { + "id": "impression-id", + "tagid": "tid", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "uri": "http://hb-test.collectiveaudience.co/rtb/bid?pid=aaaaaaaaaaaaaaaaaaaaaaaa", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "request-id", + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "imp": [ + { + "id": "impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "tid", + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ], + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "id": "some-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "123456789", + "impid": "impression-id", + "price": 2, + "adm": "adm code", + "adomain": [ + "testdomain.com" + ], + "crid": "100", + "w": 320, + "h": 50, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "123456789", + "impid": "impression-id", + "price": 2, + "adm": "adm code", + "adomain": [ + "testdomain.com" + ], + "crid": "100", + "w": 320, + "h": 50, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/beop/beoptest/exemplary/video-web.json b/adapters/beop/beoptest/exemplary/video-web.json new file mode 100644 index 0000000000..bd4ff7acfe --- /dev/null +++ b/adapters/beop/beoptest/exemplary/video-web.json @@ -0,0 +1,163 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "tmax": 1000, + "user": { + "id": "some-user" + }, + "imp": [ + { + "id": "impression-id", + "tagid": "tid", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 30, + "maxduration": 150 + }, + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "uri": "http://hb-test.collectiveaudience.co/rtb/bid?pid=aaaaaaaaaaaaaaaaaaaaaaaa", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "request-id", + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "imp": [ + { + "id": "impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 30, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "tid", + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ], + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "id": "some-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "123456789", + "impid": "impression-id", + "price": 2, + "adm": "adm code", + "adomain": [ + "testdomain.com" + ], + "crid": "100", + "w": 1280, + "h": 720, + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "123456789", + "impid": "impression-id", + "price": 2, + "adm": "adm code", + "adomain": [ + "testdomain.com" + ], + "crid": "100", + "w": 1280, + "h": 720, + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/beop/beoptest/supplemental/empty-seatbid-array.json b/adapters/beop/beoptest/supplemental/empty-seatbid-array.json new file mode 100644 index 0000000000..0b709b2b93 --- /dev/null +++ b/adapters/beop/beoptest/supplemental/empty-seatbid-array.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "tmax": 1000, + "user": { + "id": "some-user" + }, + "imp": [ + { + "id": "impression-id", + "tagid": "tid", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "uri": "http://hb-test.collectiveaudience.co/rtb/bid?pid=aaaaaaaaaaaaaaaaaaaaaaaa", + "body": { + "id": "request-id", + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "imp": [ + { + "id": "impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "tid", + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ], + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "id": "some-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "resp-id", + "seatbid": [] + } + } + } + ], + "mockResponse": { + "status": 200, + "body": "invalid response" + }, + "expectedMakeBidsErrors": [ + { + "value": "Empty SeatBid array", + "comparison": "literal" + } + ] +} diff --git a/adapters/beop/beoptest/supplemental/invalid-bid-type.json b/adapters/beop/beoptest/supplemental/invalid-bid-type.json new file mode 100644 index 0000000000..d0a8580963 --- /dev/null +++ b/adapters/beop/beoptest/supplemental/invalid-bid-type.json @@ -0,0 +1,131 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "tmax": 1000, + "user": { + "id": "some-user" + }, + "imp": [ + { + "id": "impression-id", + "tagid": "tid", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "uri": "http://hb-test.collectiveaudience.co/rtb/bid?pid=aaaaaaaaaaaaaaaaaaaaaaaa", + "body": { + "id": "request-id", + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "imp": [ + { + "id": "impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "tid", + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ], + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "id": "some-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "123456789", + "impid": "impression-id", + "price": 2, + "adm": "adm code", + "adomain": [ + "testdomain.com" + ], + "crid": "100", + "w": 320, + "h": 50, + "mtype": 3, + "ext": { + "prebid": { + "type": "audio" + } + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Failed to parse bid mType for impression \"impression-id\"", + "comparison": "literal" + } + ] +} diff --git a/adapters/beop/beoptest/supplemental/invalid-response.json b/adapters/beop/beoptest/supplemental/invalid-response.json new file mode 100644 index 0000000000..8c5537acef --- /dev/null +++ b/adapters/beop/beoptest/supplemental/invalid-response.json @@ -0,0 +1,104 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "tmax": 1000, + "user": { + "id": "some-user" + }, + "imp": [ + { + "id": "impression-id", + "tagid": "tid", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "uri": "http://hb-test.collectiveaudience.co/rtb/bid?pid=aaaaaaaaaaaaaaaaaaaaaaaa", + "body": { + "id": "request-id", + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "imp": [ + { + "id": "impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "tid", + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ], + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "id": "some-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": "invalid response" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad Server Response", + "comparison": "literal" + } + ] +} diff --git a/adapters/beop/beoptest/supplemental/missing-bidder-params.json b/adapters/beop/beoptest/supplemental/missing-bidder-params.json new file mode 100644 index 0000000000..4c2de07072 --- /dev/null +++ b/adapters/beop/beoptest/supplemental/missing-bidder-params.json @@ -0,0 +1,41 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "tmax": 1000, + "user": { + "id": "some-user" + }, + "imp": [ + { + "id": "impression-id", + "tagid": "tid", + "banner": { + "w": 320, + "h": 50 + }, + "ext": {} + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "ext.bidder not provided", + "comparison": "literal" + } + ] +} diff --git a/adapters/beop/beoptest/supplemental/status-code-bad-request.json b/adapters/beop/beoptest/supplemental/status-code-bad-request.json new file mode 100644 index 0000000000..f8c0eb2d56 --- /dev/null +++ b/adapters/beop/beoptest/supplemental/status-code-bad-request.json @@ -0,0 +1,104 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "tmax": 1000, + "user": { + "id": "some-user" + }, + "imp": [ + { + "id": "impression-id", + "tagid": "tid", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "uri": "http://hb-test.collectiveaudience.co/rtb/bid?pid=aaaaaaaaaaaaaaaaaaaaaaaa", + "body": { + "id": "request-id", + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "imp": [ + { + "id": "impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "tid", + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ], + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "id": "some-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "impression-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/beop/beoptest/supplemental/status-code-no-content.json b/adapters/beop/beoptest/supplemental/status-code-no-content.json new file mode 100644 index 0000000000..25280c2395 --- /dev/null +++ b/adapters/beop/beoptest/supplemental/status-code-no-content.json @@ -0,0 +1,98 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "tmax": 1000, + "user": { + "id": "some-user" + }, + "imp": [ + { + "id": "impression-id", + "tagid": "tid", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "uri": "http://hb-test.collectiveaudience.co/rtb/bid?pid=aaaaaaaaaaaaaaaaaaaaaaaa", + "body": { + "id": "request-id", + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "imp": [ + { + "id": "impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "tid", + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ], + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "id": "some-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "impression-id" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/beop/beoptest/supplemental/status-code-service-unavailable.json b/adapters/beop/beoptest/supplemental/status-code-service-unavailable.json new file mode 100644 index 0000000000..ce3742ab85 --- /dev/null +++ b/adapters/beop/beoptest/supplemental/status-code-service-unavailable.json @@ -0,0 +1,104 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "tmax": 1000, + "user": { + "id": "some-user" + }, + "imp": [ + { + "id": "impression-id", + "tagid": "tid", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "uri": "http://hb-test.collectiveaudience.co/rtb/bid?pid=aaaaaaaaaaaaaaaaaaaaaaaa", + "body": { + "id": "request-id", + "device": { + "ua": "useragent", + "ip": "100.100.100.100", + "language": "en" + }, + "imp": [ + { + "id": "impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "tid", + "ext": { + "bidder": { + "pid": "aaaaaaaaaaaaaaaaaaaaaaaa" + } + } + } + ], + "site": { + "page": "test.com/page", + "domain": "test.com", + "cat": [ + "IAB9-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "id": "some-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "impression-id" + ] + }, + "mockResponse": { + "status": 503 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Service Unavailable. Status Code: [ 503 ] ", + "comparison": "literal" + } + ] +} diff --git a/adapters/beop/params_test.go b/adapters/beop/params_test.go new file mode 100644 index 0000000000..63ba18c9b0 --- /dev/null +++ b/adapters/beop/params_test.go @@ -0,0 +1,49 @@ +package beop + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/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.BidderBeop, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected adverxo 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.BidderBeop, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{ "pid": "aaaaaaaaaaaaaaaaaaaaaaaa"}`, + `{ "nid": "aaaaaaaaaaaaaaaaaaaaaaaa", "ntpnid": "1234"}`, +} + +var invalidParams = []string{ + ``, + `null`, + `{}`, + `{ "fid": 5 }`, + `{ "pid": 5 }`, + `{ "pid": 5 }`, + `{ "nid": "", "nptnid": "" }`, +} diff --git a/adapters/between/between.go b/adapters/between/between.go index fe20978285..6cbb88ca16 100644 --- a/adapters/between/between.go +++ b/adapters/between/between.go @@ -9,12 +9,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type BetweenAdapter struct { diff --git a/adapters/between/between_test.go b/adapters/between/between_test.go index 61f759126b..1a33e77102 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/between/params_test.go b/adapters/between/params_test.go index 5e30dba116..7d16056f55 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 bafa5791d8..4e026aa0f4 100644 --- a/adapters/beyondmedia/beyondmedia.go +++ b/adapters/beyondmedia/beyondmedia.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/beyondmedia/beyondmedia_test.go b/adapters/beyondmedia/beyondmedia_test.go index 94eb5bd741..6050f70488 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/beyondmedia/params_test.go b/adapters/beyondmedia/params_test.go index 2f6d969f1a..9804f12bde 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bidder.go b/adapters/bidder.go index fb0ec07e03..0be99b0080 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/v3/config" - "github.com/prebid/prebid-server/v3/currency" - "github.com/prebid/prebid-server/v3/metrics" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // Bidder describes how to connect to external demand. diff --git a/adapters/bidmachine/bidmachine.go b/adapters/bidmachine/bidmachine.go index 81a72cdac5..47fd8b90f1 100644 --- a/adapters/bidmachine/bidmachine.go +++ b/adapters/bidmachine/bidmachine.go @@ -12,12 +12,13 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/urlutil" ) type adapter struct { @@ -184,6 +185,9 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co const UndefinedMediaType = openrtb_ext.BidType("") func (a *adapter) buildEndpointURL(params openrtb_ext.ExtImpBidmachine) (string, error) { + if !urlutil.IsSafeHost(params.Host) { + return "", &errortypes.BadInput{Message: "Failed to create final URL with provided host"} + } endpointParams := macros.EndpointTemplateParams{Host: params.Host} uriString, errMacros := macros.ResolveMacros(a.endpoint, endpointParams) if errMacros != nil { diff --git a/adapters/bidmachine/bidmachine_test.go b/adapters/bidmachine/bidmachine_test.go index dc26633c4f..f303e49cde 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/bidmachine/bidmachinetest/supplemental/invalid-host.json b/adapters/bidmachine/bidmachinetest/supplemental/invalid-host.json new file mode 100644 index 0000000000..3182d6bf4a --- /dev/null +++ b/adapters/bidmachine/bidmachinetest/supplemental/invalid-host.json @@ -0,0 +1,32 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-impression-id-1", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "host": "evil.com/path?redirect=http://attacker.com#", + "path": "auction/rtb/v2", + "seller_id": "1" + } + } + } + ] + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Failed to create final URL with provided host", + "comparison": "literal" + } + ] +} diff --git a/adapters/bidmachine/params_test.go b/adapters/bidmachine/params_test.go index 319fef8902..1f51f92a75 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -34,8 +34,12 @@ func TestInvalidParams(t *testing.T) { } var validParams = []string{ - `{"seller_id":"1", "host":"api-eu", "path":"auction/rtb/v2"}`, - `{"seller_id":"1", "host":"api-us", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"host", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"host.example.com", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"host.example.com:8080", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"host-example.test", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"Host.Example.com", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"localhost:3000", "path":"auction/rtb/v2"}`, } var invalidParams = []string{ @@ -47,32 +51,19 @@ var invalidParams = []string{ `[]`, `{}`, `{"some_random_field":""}`, - `{"seller_id":""}`, - `{"seller_id": 1}`, - `{"seller_id": 1.2}`, - `{"seller_id": null}`, - `{"seller_id": true}`, - `{"seller_id": []}`, - `{"seller_id": {}}`, - `{"host":""}`, - `{"host": 1}`, - `{"host": 1.2}`, - `{"host": null}`, - `{"host": true}`, - `{"host": []}`, - `{"host": {}}`, - `{"path":""}`, - `{"path": 1}`, - `{"path": 1.2}`, - `{"path": null}`, - `{"path": true}`, - `{"path": []}`, - `{"path": {}}`, - `{"seller_id":"", "path": "", host: ""}`, - `{"seller_id": 1, "path": 2, host: 3}`, - `{"seller_id": 1.2}, "path": 5.5, host: 3.3`, - `{"seller_id": null, "path": null, host: null}`, - `{"seller_id": true, "path": false, host: true}`, - `{"seller_id": [], "path": [], host: []}`, - `{"seller_id": {}, "path": {}, host: {}}`, + `{"seller_id":"", "host":"host", "path":"auction/rtb/v2"}`, + `{"host":"host", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"host", "path":""}`, + `{"seller_id":"1", "host":"host"}`, + `{"seller_id":"1", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"/path", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"//evil.com", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"host/path", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"host?query=1", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"host#fragment", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"user@host", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"https://host.com", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"host:notaport", "path":"auction/rtb/v2"}`, + `{"seller_id":"1", "host":"host:8080:extra", "path":"auction/rtb/v2"}`, } diff --git a/adapters/bidmatic/bidmatic.go b/adapters/bidmatic/bidmatic.go index 32b7a2ee88..06678021dc 100644 --- a/adapters/bidmatic/bidmatic.go +++ b/adapters/bidmatic/bidmatic.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/bidmatic/bidmatic_test.go b/adapters/bidmatic/bidmatic_test.go index b546eca545..f803c898ad 100644 --- a/adapters/bidmatic/bidmatic_test.go +++ b/adapters/bidmatic/bidmatic_test.go @@ -3,9 +3,9 @@ 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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bidmatic/params_test.go b/adapters/bidmatic/params_test.go index bfea9fddae..cc13f7b979 100644 --- a/adapters/bidmatic/params_test.go +++ b/adapters/bidmatic/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/bidmatic.json diff --git a/adapters/bidmyadz/bidmyadz.go b/adapters/bidmyadz/bidmyadz.go index b2f8cda564..87c92eb3bb 100644 --- a/adapters/bidmyadz/bidmyadz.go +++ b/adapters/bidmyadz/bidmyadz.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/bidmyadz/bidmyadz_test.go b/adapters/bidmyadz/bidmyadz_test.go index f01af44cff..53b4bcc592 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bidmyadz/params_test.go b/adapters/bidmyadz/params_test.go index fca34b1024..e8a50bd7ee 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/bidscube/bidscube.go b/adapters/bidscube/bidscube.go index 8ccd794f86..2bb9dc25c7 100644 --- a/adapters/bidscube/bidscube.go +++ b/adapters/bidscube/bidscube.go @@ -9,11 +9,11 @@ import ( "github.com/buger/jsonparser" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/bidscube/bidscube_test.go b/adapters/bidscube/bidscube_test.go index 5396ccd426..aec8219b84 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bidscube/params_test.go b/adapters/bidscube/params_test.go index 9f368f939a..00bc51dd1e 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 555abff0c7..5172db1bb8 100644 --- a/adapters/bidstack/bidstack.go +++ b/adapters/bidstack/bidstack.go @@ -9,10 +9,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/adapters/bidstack/bidstack_test.go b/adapters/bidstack/bidstack_test.go index 9010ce5014..14d506497b 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bidstack/params_test.go b/adapters/bidstack/params_test.go index 3cca0f447b..cc24029280 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/bidtheatre/bidtheatre.go b/adapters/bidtheatre/bidtheatre.go index 8d3b149c7e..6e56171b2d 100644 --- a/adapters/bidtheatre/bidtheatre.go +++ b/adapters/bidtheatre/bidtheatre.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/bidtheatre/bidtheatre_test.go b/adapters/bidtheatre/bidtheatre_test.go index 8a4daf5fbe..ca78a03f27 100644 --- a/adapters/bidtheatre/bidtheatre_test.go +++ b/adapters/bidtheatre/bidtheatre_test.go @@ -2,9 +2,9 @@ package bidtheatre import ( "github.com/prebid/openrtb/v20/openrtb2" - "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/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "strings" "testing" ) diff --git a/adapters/bidtheatre/params_test.go b/adapters/bidtheatre/params_test.go index 64870afcba..51caec5f94 100644 --- a/adapters/bidtheatre/params_test.go +++ b/adapters/bidtheatre/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bigoad/bigoad.go b/adapters/bigoad/bigoad.go index e968139d59..7e4edd51fc 100644 --- a/adapters/bigoad/bigoad.go +++ b/adapters/bigoad/bigoad.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/bigoad/bigoad_test.go b/adapters/bigoad/bigoad_test.go index 7c51c8f80d..a171d66dc9 100644 --- a/adapters/bigoad/bigoad_test.go +++ b/adapters/bigoad/bigoad_test.go @@ -3,9 +3,9 @@ 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/bigoad/param_test.go b/adapters/bigoad/param_test.go index 772bcb7721..9f456f65df 100644 --- a/adapters/bigoad/param_test.go +++ b/adapters/bigoad/param_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/blasto/blasto.go b/adapters/blasto/blasto.go index e9917d0885..c02c4a1ce7 100644 --- a/adapters/blasto/blasto.go +++ b/adapters/blasto/blasto.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/blasto/blasto_test.go b/adapters/blasto/blasto_test.go index 9b09c19ae6..4bce53bcde 100644 --- a/adapters/blasto/blasto_test.go +++ b/adapters/blasto/blasto_test.go @@ -3,9 +3,9 @@ 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/blasto/params_test.go b/adapters/blasto/params_test.go index c23f162d03..762b51185d 100644 --- a/adapters/blasto/params_test.go +++ b/adapters/blasto/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/bliink/bliink.go b/adapters/bliink/bliink.go index 900c1de7ee..d5ce144c8c 100644 --- a/adapters/bliink/bliink.go +++ b/adapters/bliink/bliink.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/bliink/bliink_test.go b/adapters/bliink/bliink_test.go index d5fa3aa58e..404f90127b 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bliink/params_test.go b/adapters/bliink/params_test.go index 646ab96e4c..8b3620e962 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/blis/blis.go b/adapters/blis/blis.go index ed701a2241..617c6b82e6 100644 --- a/adapters/blis/blis.go +++ b/adapters/blis/blis.go @@ -8,13 +8,13 @@ import ( "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/iterutil" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/iterutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/blis/blis_test.go b/adapters/blis/blis_test.go index b9fcc9836a..7ae808d8e8 100644 --- a/adapters/blis/blis_test.go +++ b/adapters/blis/blis_test.go @@ -4,9 +4,9 @@ import ( "github.com/stretchr/testify/assert" "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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/require" ) diff --git a/adapters/blis/params_test.go b/adapters/blis/params_test.go index 2a62836a06..b1535e8844 100644 --- a/adapters/blis/params_test.go +++ b/adapters/blis/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/adapters/blue/blue.go b/adapters/blue/blue.go index 08b5167dd0..6f9537507f 100644 --- a/adapters/blue/blue.go +++ b/adapters/blue/blue.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/blue/blue_test.go b/adapters/blue/blue_test.go index 696d855d6a..815cbaf561 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestBidderBlue(t *testing.T) { diff --git a/adapters/blue/params_test.go b/adapters/blue/params_test.go index 27b1e02ea8..aac600299c 100644 --- a/adapters/blue/params_test.go +++ b/adapters/blue/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bluesea/bluesea.go b/adapters/bluesea/bluesea.go index 0428b22b6c..835f98c48e 100644 --- a/adapters/bluesea/bluesea.go +++ b/adapters/bluesea/bluesea.go @@ -7,11 +7,11 @@ import ( "net/url" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/bluesea/bluesea_test.go b/adapters/bluesea/bluesea_test.go index 2d0b5bdaca..df4ed7d6ec 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bluesea/params_test.go b/adapters/bluesea/params_test.go index 79d15d0baa..f9f7ee5b90 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 6f48df6d4d..f1c8fd9719 100644 --- a/adapters/bmtm/brightmountainmedia.go +++ b/adapters/bmtm/brightmountainmedia.go @@ -7,11 +7,11 @@ import ( "strconv" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/bmtm/brightmountainmedia_test.go b/adapters/bmtm/brightmountainmedia_test.go index 28af575c57..51ec50e6cd 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bmtm/params_test.go b/adapters/bmtm/params_test.go index f6f8b6105e..a2ff1104c0 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/boldwin/boldwin.go b/adapters/boldwin/boldwin.go index 2dbb145428..52f545086e 100644 --- a/adapters/boldwin/boldwin.go +++ b/adapters/boldwin/boldwin.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/boldwin/boldwin_test.go b/adapters/boldwin/boldwin_test.go index 1a270fcfe9..a6d3e3238e 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/boldwin/params_test.go b/adapters/boldwin/params_test.go index 627af2418f..b122376848 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/boldwin_rapid/boldwin_rapid.go b/adapters/boldwin_rapid/boldwin_rapid.go index 1904cd8aca..62d2131fea 100644 --- a/adapters/boldwin_rapid/boldwin_rapid.go +++ b/adapters/boldwin_rapid/boldwin_rapid.go @@ -8,11 +8,11 @@ import ( "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/macros" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/boldwin_rapid/boldwin_rapid_test.go b/adapters/boldwin_rapid/boldwin_rapid_test.go index 58e03ca2aa..da55e420ae 100644 --- a/adapters/boldwin_rapid/boldwin_rapid_test.go +++ b/adapters/boldwin_rapid/boldwin_rapid_test.go @@ -6,10 +6,10 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/adapters/boldwin_rapid/params_test.go b/adapters/boldwin_rapid/params_test.go index d43843271a..eef731350d 100644 --- a/adapters/boldwin_rapid/params_test.go +++ b/adapters/boldwin_rapid/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/brave/brave.go b/adapters/brave/brave.go index 4cca024f43..595df0ea0d 100755 --- a/adapters/brave/brave.go +++ b/adapters/brave/brave.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/brave/brave_test.go b/adapters/brave/brave_test.go index a1ea0cd70d..aceebd3a56 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/brave/params_test.go b/adapters/brave/params_test.go index fd0a6f8c63..06ec9f5f55 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bwx/bwx.go b/adapters/bwx/bwx.go index 55e64a05c2..22b9451934 100644 --- a/adapters/bwx/bwx.go +++ b/adapters/bwx/bwx.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type bidType struct { diff --git a/adapters/bwx/bwx_test.go b/adapters/bwx/bwx_test.go index 10246ee8a8..edd87acf62 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/bwx/params_test.go b/adapters/bwx/params_test.go index 515fbd5073..cd5d969bbf 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/cadent_aperture_mx/cadentaperturemx.go b/adapters/cadent_aperture_mx/cadentaperturemx.go index 58902bad55..9d62c1a5e6 100644 --- a/adapters/cadent_aperture_mx/cadentaperturemx.go +++ b/adapters/cadent_aperture_mx/cadentaperturemx.go @@ -11,11 +11,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/cadent_aperture_mx/cadentaperturemx_test.go b/adapters/cadent_aperture_mx/cadentaperturemx_test.go index 7a951555d0..a17eac4b66 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/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 d505bd8329..8fc1377c6a 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/ccx/ccx.go b/adapters/ccx/ccx.go index 64bb599afd..7685e624a6 100644 --- a/adapters/ccx/ccx.go +++ b/adapters/ccx/ccx.go @@ -6,12 +6,12 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" - "github.com/prebid/prebid-server/v3/adapters" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/ccx/ccx_test.go b/adapters/ccx/ccx_test.go index de095d7259..3c68e9ccc0 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/ccx/params_test.go b/adapters/ccx/params_test.go index ff600fada1..2d296bc883 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/clydo/clydo.go b/adapters/clydo/clydo.go index 0b06bd74d8..967aab5682 100644 --- a/adapters/clydo/clydo.go +++ b/adapters/clydo/clydo.go @@ -6,12 +6,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/clydo/clydo_test.go b/adapters/clydo/clydo_test.go index ef21d1e486..c381fc6adc 100644 --- a/adapters/clydo/clydo_test.go +++ b/adapters/clydo/clydo_test.go @@ -3,9 +3,9 @@ package clydo 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/clydo/params_test.go b/adapters/clydo/params_test.go index 779c7eeadd..f3172f83b7 100644 --- a/adapters/clydo/params_test.go +++ b/adapters/clydo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/cointraffic/cointraffic.go b/adapters/cointraffic/cointraffic.go index 781d8def81..d5aff00551 100644 --- a/adapters/cointraffic/cointraffic.go +++ b/adapters/cointraffic/cointraffic.go @@ -5,10 +5,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/cointraffic/cointraffic_test.go b/adapters/cointraffic/cointraffic_test.go index 133dfd2af2..c73d8d6b3a 100644 --- a/adapters/cointraffic/cointraffic_test.go +++ b/adapters/cointraffic/cointraffic_test.go @@ -5,9 +5,9 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testsDir = "cointraffictest" diff --git a/adapters/cointraffic/params_test.go b/adapters/cointraffic/params_test.go index 484a72c66b..3d0044d94b 100644 --- a/adapters/cointraffic/params_test.go +++ b/adapters/cointraffic/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/cointraffic.json diff --git a/adapters/coinzilla/coinzilla.go b/adapters/coinzilla/coinzilla.go index 21e321406c..eeec012a34 100644 --- a/adapters/coinzilla/coinzilla.go +++ b/adapters/coinzilla/coinzilla.go @@ -6,12 +6,12 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" - "github.com/prebid/prebid-server/v3/adapters" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { diff --git a/adapters/coinzilla/coinzilla_test.go b/adapters/coinzilla/coinzilla_test.go index 830028f24f..fff81adf18 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testsDir = "coinzillatest" diff --git a/adapters/coinzilla/params_test.go b/adapters/coinzilla/params_test.go index d174b1441a..61586a8910 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/colossus/colossus.go b/adapters/colossus/colossus.go index 0fc1e50a29..5f3b2d1c7b 100644 --- a/adapters/colossus/colossus.go +++ b/adapters/colossus/colossus.go @@ -7,11 +7,11 @@ import ( "github.com/buger/jsonparser" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type ColossusAdapter struct { diff --git a/adapters/colossus/colossus_test.go b/adapters/colossus/colossus_test.go index 227bd635ae..903cd2ec65 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/colossus/params_test.go b/adapters/colossus/params_test.go index bf924e4eae..d4e80e4679 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 28f46bc7e2..0ab775a513 100644 --- a/adapters/compass/compass.go +++ b/adapters/compass/compass.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/compass/compass_test.go b/adapters/compass/compass_test.go index 7aed7616de..9e043d1c60 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/compass/params_test.go b/adapters/compass/params_test.go index edabac2975..6de87dfe03 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/concert/concert.go b/adapters/concert/concert.go index adf7144274..5ac3269006 100644 --- a/adapters/concert/concert.go +++ b/adapters/concert/concert.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/concert/concert_test.go b/adapters/concert/concert_test.go index d6cea80fb9..397043b3da 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/concert/params_test.go b/adapters/concert/params_test.go index b8ec65bda8..512f016482 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/connatix/connatix.go b/adapters/connatix/connatix.go index c479a2892f..fbd1af35e9 100644 --- a/adapters/connatix/connatix.go +++ b/adapters/connatix/connatix.go @@ -9,11 +9,11 @@ import ( "github.com/buger/jsonparser" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/adapters/connatix/connatix_test.go b/adapters/connatix/connatix_test.go index 018926ef25..fdaa76beef 100644 --- a/adapters/connatix/connatix_test.go +++ b/adapters/connatix/connatix_test.go @@ -3,9 +3,9 @@ package connatix 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/connatix/models.go b/adapters/connatix/models.go index aebd51d097..3462829eae 100644 --- a/adapters/connatix/models.go +++ b/adapters/connatix/models.go @@ -1,7 +1,7 @@ package connatix import ( - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type adapter struct { diff --git a/adapters/connatix/params_test.go b/adapters/connatix/params_test.go index 254f660c1b..beb681aa7c 100644 --- a/adapters/connatix/params_test.go +++ b/adapters/connatix/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/connatix.json diff --git a/adapters/connectad/connectad.go b/adapters/connectad/connectad.go index dd13bc3764..146e583eaf 100644 --- a/adapters/connectad/connectad.go +++ b/adapters/connectad/connectad.go @@ -8,11 +8,11 @@ import ( "strconv" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type ConnectAdAdapter struct { diff --git a/adapters/connectad/connectad_test.go b/adapters/connectad/connectad_test.go index 4563e0045f..ac876a7a67 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/connectad/params_test.go b/adapters/connectad/params_test.go index dc7c40be72..12dd9c7be9 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/consumable/consumable.go b/adapters/consumable/consumable.go index 9b80fb1459..47d1ba3ea0 100644 --- a/adapters/consumable/consumable.go +++ b/adapters/consumable/consumable.go @@ -5,11 +5,11 @@ import ( "fmt" "net/http" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) diff --git a/adapters/consumable/consumable_test.go b/adapters/consumable/consumable_test.go index 200d6159ea..76a28d40d1 100644 --- a/adapters/consumable/consumable_test.go +++ b/adapters/consumable/consumable_test.go @@ -6,11 +6,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/consumable/params_test.go b/adapters/consumable/params_test.go index 3820acc737..6584982d81 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/consumable.json diff --git a/adapters/contxtful/contxtful.go b/adapters/contxtful/contxtful.go index 3dd8b5b2b9..3513579ffe 100644 --- a/adapters/contxtful/contxtful.go +++ b/adapters/contxtful/contxtful.go @@ -6,12 +6,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // ContxtfulRequestPayload represents the complete request payload structure diff --git a/adapters/contxtful/contxtful_relay_test.go b/adapters/contxtful/contxtful_relay_test.go index 61f9773ab5..c668047c1f 100644 --- a/adapters/contxtful/contxtful_relay_test.go +++ b/adapters/contxtful/contxtful_relay_test.go @@ -5,9 +5,9 @@ import ( "testing" "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/contxtful/contxtful_test.go b/adapters/contxtful/contxtful_test.go index b1fa229b6d..846144e9b4 100644 --- a/adapters/contxtful/contxtful_test.go +++ b/adapters/contxtful/contxtful_test.go @@ -9,11 +9,11 @@ import ( "net/http" "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/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/adapters/contxtful/params_test.go b/adapters/contxtful/params_test.go index bc7321f892..34831e1616 100644 --- a/adapters/contxtful/params_test.go +++ b/adapters/contxtful/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/conversant/conversant.go b/adapters/conversant/conversant.go index 035ee14bae..f5db218286 100644 --- a/adapters/conversant/conversant.go +++ b/adapters/conversant/conversant.go @@ -8,11 +8,12 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/version" ) type ConversantAdapter struct { @@ -84,7 +85,10 @@ func (c *ConversantAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo * func parseCnvrParams(imp *openrtb2.Imp, cnvrExt openrtb_ext.ExtImpConversant, reqInfo *adapters.ExtraRequestInfo) []error { imp.DisplayManager = "prebid-s2s" - imp.DisplayManagerVer = "2.0.0" + + if version.Ver != "" { + imp.DisplayManagerVer = version.Ver + } if imp.BidFloor <= 0 && cnvrExt.BidFloor > 0 { imp.BidFloor = cnvrExt.BidFloor diff --git a/adapters/conversant/conversant_test.go b/adapters/conversant/conversant_test.go index eeb5756471..563b229997 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/conversant/conversanttest/exemplary/banner.json b/adapters/conversant/conversanttest/exemplary/banner.json index 8523bb671d..c84c9405db 100644 --- a/adapters/conversant/conversanttest/exemplary/banner.json +++ b/adapters/conversant/conversanttest/exemplary/banner.json @@ -42,7 +42,6 @@ "secure": 1, "bidfloor": 0.01, "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "banner": { "format": [{"w": 300, "h": 250}] }, diff --git a/adapters/conversant/conversanttest/exemplary/simple-native.json b/adapters/conversant/conversanttest/exemplary/simple-native.json index f1c67e548a..e32dad2f08 100644 --- a/adapters/conversant/conversanttest/exemplary/simple-native.json +++ b/adapters/conversant/conversanttest/exemplary/simple-native.json @@ -35,7 +35,6 @@ "secure": 1, "bidfloor": 0.01, "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "ext": { "bidder": { "site_id": "108060", @@ -97,4 +96,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/conversant/conversanttest/exemplary/simple_app.json b/adapters/conversant/conversanttest/exemplary/simple_app.json index a4c825e1f6..e3ef3db1c2 100644 --- a/adapters/conversant/conversanttest/exemplary/simple_app.json +++ b/adapters/conversant/conversanttest/exemplary/simple_app.json @@ -46,7 +46,6 @@ "secure": 1, "bidfloor": 0.01, "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "banner": { "format": [{"w": 300, "h": 250}] }, diff --git a/adapters/conversant/conversanttest/exemplary/simple_audio_app.json b/adapters/conversant/conversanttest/exemplary/simple_audio_app.json index fd0b091085..64ae162520 100644 --- a/adapters/conversant/conversanttest/exemplary/simple_audio_app.json +++ b/adapters/conversant/conversanttest/exemplary/simple_audio_app.json @@ -42,7 +42,6 @@ "secure": 1, "bidfloor": 0.01, "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "audio": { "mimes": [ "audio/vnd.wav", "audio/mpeg", "audio/mp4" ], "protocols": [3,6,7,8] diff --git a/adapters/conversant/conversanttest/exemplary/simple_audio_site.json b/adapters/conversant/conversanttest/exemplary/simple_audio_site.json index fb74e0b673..d2b4f849c3 100644 --- a/adapters/conversant/conversanttest/exemplary/simple_audio_site.json +++ b/adapters/conversant/conversanttest/exemplary/simple_audio_site.json @@ -44,7 +44,6 @@ "secure": 1, "bidfloor": 0.01, "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "audio": { "mimes": [ "audio/vnd.wav", "audio/mpeg", "audio/mp4" ], "protocols": [3,6,7,8] diff --git a/adapters/conversant/conversanttest/exemplary/video.json b/adapters/conversant/conversanttest/exemplary/video.json index 322e28ad51..023b159cd9 100644 --- a/adapters/conversant/conversanttest/exemplary/video.json +++ b/adapters/conversant/conversanttest/exemplary/video.json @@ -63,7 +63,6 @@ "bidfloor": 25.0, "bidfloorcur": "USD", "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "video": { "w": 300, "h": 250, diff --git a/adapters/conversant/conversanttest/supplemental/server_badresponse.json b/adapters/conversant/conversanttest/supplemental/server_badresponse.json index 26c74eaa66..60e9b78bf3 100644 --- a/adapters/conversant/conversanttest/supplemental/server_badresponse.json +++ b/adapters/conversant/conversanttest/supplemental/server_badresponse.json @@ -31,7 +31,6 @@ { "id": "1", "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "banner": { "format": [{"w": 300, "h": 250}] }, diff --git a/adapters/conversant/conversanttest/supplemental/server_nocontent.json b/adapters/conversant/conversanttest/supplemental/server_nocontent.json index ca33f470a5..4faff08b96 100644 --- a/adapters/conversant/conversanttest/supplemental/server_nocontent.json +++ b/adapters/conversant/conversanttest/supplemental/server_nocontent.json @@ -31,7 +31,6 @@ { "id": "1", "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "banner": { "format": [{"w": 300, "h": 250}] }, diff --git a/adapters/conversant/conversanttest/supplemental/server_unknownstatus.json b/adapters/conversant/conversanttest/supplemental/server_unknownstatus.json index 129b6fba02..acb9741435 100644 --- a/adapters/conversant/conversanttest/supplemental/server_unknownstatus.json +++ b/adapters/conversant/conversanttest/supplemental/server_unknownstatus.json @@ -31,7 +31,6 @@ { "id": "1", "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "banner": { "format": [{"w": 300, "h": 250}] }, diff --git a/adapters/conversant/conversanttest/supplemental/test_params.json b/adapters/conversant/conversanttest/supplemental/test_params.json index 41366dbe19..ce3efc35d0 100644 --- a/adapters/conversant/conversanttest/supplemental/test_params.json +++ b/adapters/conversant/conversanttest/supplemental/test_params.json @@ -108,7 +108,6 @@ "secure": 1, "tagid": "mytag", "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "video": { "api": [1,2], "maxduration": 60, @@ -127,7 +126,6 @@ "secure": 1, "tagid": "mytag", "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "video": { "api": [1,2], "maxduration": 60, @@ -155,7 +153,6 @@ "secure": 1, "tagid": "mytag", "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "video": { "api": [1,2], "maxduration": 60, @@ -183,7 +180,6 @@ "secure": 1, "tagid": "mytag", "displaymanager": "prebid-s2s", - "displaymanagerver": "2.0.0", "video": { "api": [1,2], "maxduration": 60, diff --git a/adapters/copper6ssp/copper6ssp.go b/adapters/copper6ssp/copper6ssp.go index 77154dd686..85f4674858 100644 --- a/adapters/copper6ssp/copper6ssp.go +++ b/adapters/copper6ssp/copper6ssp.go @@ -6,10 +6,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/copper6ssp/copper6ssp_test.go b/adapters/copper6ssp/copper6ssp_test.go index 75ca8ee404..9f98ce4ede 100644 --- a/adapters/copper6ssp/copper6ssp_test.go +++ b/adapters/copper6ssp/copper6ssp_test.go @@ -3,9 +3,9 @@ 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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/copper6ssp/params_test.go b/adapters/copper6ssp/params_test.go index 427cf63b26..bd9d84ee3d 100644 --- a/adapters/copper6ssp/params_test.go +++ b/adapters/copper6ssp/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/cpmstar/cpmstar.go b/adapters/cpmstar/cpmstar.go index 9aa3026c77..67a94ac239 100644 --- a/adapters/cpmstar/cpmstar.go +++ b/adapters/cpmstar/cpmstar.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type Adapter struct { diff --git a/adapters/cpmstar/cpmstar_test.go b/adapters/cpmstar/cpmstar_test.go index 478b898943..e007583af1 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/cpmstar/params_test.go b/adapters/cpmstar/params_test.go index aea148c82f..0fbb0d2530 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 2bfa35ade0..6779a20f87 100644 --- a/adapters/criteo/criteo.go +++ b/adapters/criteo/criteo.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/criteo/criteo_test.go b/adapters/criteo/criteo_test.go index 70392c6cd5..f3fd11ba01 100644 --- a/adapters/criteo/criteo_test.go +++ b/adapters/criteo/criteo_test.go @@ -7,9 +7,9 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/criteo/params_test.go b/adapters/criteo/params_test.go index 240eeea43a..98f5f77f38 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 2d297f78e9..99deac6b7c 100644 --- a/adapters/cwire/cwire.go +++ b/adapters/cwire/cwire.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) /* @@ -91,12 +91,28 @@ func (a *adapter) MakeBids(bidReq *openrtb2.BidRequest, unused *adapters.Request bidderResponse.Currency = resp.Cur for _, sb := range resp.SeatBid { for i := range sb.Bid { + bidType, err := getBidType(sb.Bid[i]) + if err != nil { + return nil, []error{err} + } bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{ Bid: &sb.Bid[i], - BidType: openrtb_ext.BidTypeBanner, + BidType: bidType, }) } } return bidderResponse, 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 + } + + return "", fmt.Errorf("could not define media type for C Wire impression: %s", bid.ImpID) +} diff --git a/adapters/cwire/cwire_test.go b/adapters/cwire/cwire_test.go index 726c3caf09..2e21ef3c6e 100644 --- a/adapters/cwire/cwire_test.go +++ b/adapters/cwire/cwire_test.go @@ -1,11 +1,17 @@ package cwire import ( + "math" + "net/http" "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/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestJsonSamples(t *testing.T) { @@ -27,3 +33,30 @@ func TestJsonSamples(t *testing.T) { adapterstest.RunJSONBidderTest(t, "cwiretest", bidder) } + +func TestMakeRequestsMarshalError(t *testing.T) { + bidder := &adapter{} + request := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: math.NaN()}}, + } + + requests, errs := bidder.MakeRequests(request, nil) + + assert.Nil(t, requests) + require.Len(t, errs, 1) + assert.EqualError(t, errs[0], "Error while encoding OpenRTB BidRequest: json: unsupported value: NaN") +} + +func TestMakeBidsUnknownMarkupType(t *testing.T) { + bidder := &adapter{} + httpResponse := &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{"seatbid":[{"bid":[{"impid":"imp-1","mtype":0}]}]}`), + } + + response, errs := bidder.MakeBids(nil, nil, httpResponse) + + assert.Nil(t, response) + require.Len(t, errs, 1) + assert.EqualError(t, errs[0], "could not define media type for C Wire impression: imp-1") +} diff --git a/adapters/cwire/cwiretest/exemplary/video.json b/adapters/cwire/cwiretest/exemplary/video.json new file mode 100644 index 0000000000..980522c090 --- /dev/null +++ b/adapters/cwire/cwiretest/exemplary/video.json @@ -0,0 +1,152 @@ +{ + "mockBidRequest": { + "id": "80ce30c53c16e6ede735f123ef6e32361bfc7b22", + "cur": [ + "CHF" + ], + "imp": [ + { + "id": "103", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "placementId": 15, + "domainId": 42 + } + } + } + ], + "site": { + "page": "http://www.foobar.com/1234.html" + }, + "device": { + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:108.0) Gecko/20100101 Firefox/108.0" + }, + "user": { + "id": "55816b39711f9b5acf3b90e313ed29e51665623f", + "geo": { + "country": "ch", + "region": "basel-stadt", + "city": "basel" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://cwi.re/prebid/adapter-endpoint", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "80ce30c53c16e6ede735f123ef6e32361bfc7b22", + "cur": [ + "CHF" + ], + "imp": [ + { + "id": "103", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "placementId": 15, + "domainId": 42 + } + } + } + ], + "site": { + "page": "http://www.foobar.com/1234.html" + }, + "device": { + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:108.0) Gecko/20100101 Firefox/108.0" + }, + "user": { + "id": "55816b39711f9b5acf3b90e313ed29e51665623f", + "geo": { + "country": "ch", + "region": "basel-stadt", + "city": "basel" + } + } + }, + "impIDs": [ + "103" + ] + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "id": "80ce30c53c16e6ede735f123ef6e32361bfc7b22", + "cur": "CHF", + "seatbid": [ + { + "seat": "cwire", + "group": 0, + "bid": [ + { + "id": "334", + "impid": "103", + "price": 8.00, + "crid": "9999", + "adm": "", + "w": 640, + "h": 480, + "nurl": "https://embed.cwi.re/delivery/prebid-server/win/334", + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "CHF", + "bids": [ + { + "bid": { + "id": "334", + "impid": "103", + "price": 8.00, + "crid": "9999", + "adm": "", + "w": 640, + "h": 480, + "nurl": "https://embed.cwi.re/delivery/prebid-server/win/334", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/cwire/params_test.go b/adapters/cwire/params_test.go index 534a9c0923..b1577f86be 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 a0e318524d..7d911d98c0 100644 --- a/adapters/datablocks/datablocks.go +++ b/adapters/datablocks/datablocks.go @@ -8,12 +8,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type DatablocksAdapter struct { diff --git a/adapters/datablocks/datablocks_test.go b/adapters/datablocks/datablocks_test.go index f44204c7c5..762bf6cc0f 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/decenterads/decenterads.go b/adapters/decenterads/decenterads.go index 7981f60c97..26dd5634fb 100644 --- a/adapters/decenterads/decenterads.go +++ b/adapters/decenterads/decenterads.go @@ -8,11 +8,11 @@ import ( "strconv" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/decenterads/decenterads_test.go b/adapters/decenterads/decenterads_test.go index ba3cefa989..97d72fba62 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/decenterads/params_test.go b/adapters/decenterads/params_test.go index 7672892ed0..5e08265528 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 a1867cdadc..cb83e1ead7 100644 --- a/adapters/deepintent/deepintent.go +++ b/adapters/deepintent/deepintent.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const displayManager string = "di_prebid" diff --git a/adapters/deepintent/deepintent_test.go b/adapters/deepintent/deepintent_test.go index 6b2d216db3..4f8c2219b1 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/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" - "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/deepintent/params_test.go b/adapters/deepintent/params_test.go index b45eaa67a8..e1f8cc1f8e 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 7f775b88c3..fcfef769e0 100644 --- a/adapters/definemedia/definemedia.go +++ b/adapters/definemedia/definemedia.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/definemedia/definemedia_test.go b/adapters/definemedia/definemedia_test.go index 9d5b39b5b7..377c491041 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/definemedia/params_test.go b/adapters/definemedia/params_test.go index bd3912719b..9af4ba1b20 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/dianomi/dianomi.go b/adapters/dianomi/dianomi.go index 5f16547de1..315a030a07 100644 --- a/adapters/dianomi/dianomi.go +++ b/adapters/dianomi/dianomi.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/dianomi/dianomi_test.go b/adapters/dianomi/dianomi_test.go index 23a42fa69c..da4a0d6644 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/dianomi/params_test.go b/adapters/dianomi/params_test.go index 294bfa977f..dd9aeb1449 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 index 5e63fe2b5a..4868777bd5 100644 --- a/adapters/displayio/displayio.go +++ b/adapters/displayio/displayio.go @@ -8,12 +8,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { @@ -130,7 +130,7 @@ func (adapter *adapter) MakeBids(bidReq *openrtb2.BidRequest, _ *adapters.Reques var bidResp openrtb2.BidResponse if err := jsonutil.Unmarshal(responseData.Body, &bidResp); err != nil { - msg := fmt.Sprintf("Bad server response: %d", err) + msg := fmt.Sprintf("Bad server response: %v", err) return nil, []error{&errortypes.BadServerResponse{Message: msg}} } @@ -194,8 +194,14 @@ func getBidMediaTypeFromMtype(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { return openrtb_ext.BidTypeBanner, nil case openrtb2.MarkupVideo: return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil default: - return "", fmt.Errorf("unexpected media type for bid: %s", bid.ImpID) + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("unsupported MType %d", bid.MType), + } } } diff --git a/adapters/displayio/displayio_test.go b/adapters/displayio/displayio_test.go index b591abeb42..f7f32c8a8a 100644 --- a/adapters/displayio/displayio_test.go +++ b/adapters/displayio/displayio_test.go @@ -3,9 +3,9 @@ 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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/displayio/displayiotest/exemplary/simple-audio.json b/adapters/displayio/displayiotest/exemplary/simple-audio.json new file mode 100644 index 0000000000..e531760064 --- /dev/null +++ b/adapters/displayio/displayiotest/exemplary/simple-audio.json @@ -0,0 +1,116 @@ +{ + "mockBidRequest": { + "app": { + "id": "1011" + }, + "id": "requestId10111011101110111011", + "imp": [ + { + "audio": { + "mimes": [ + "audio/mpeg" + ] + }, + "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": [ + { + "audio": { + "mimes": [ + "audio/mpeg" + ] + }, + "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" + ], + "mtype": 3 + } + ], + "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" + ], + "mtype": 3 + }, + "type": "audio" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/displayio/displayiotest/exemplary/simple-native.json b/adapters/displayio/displayiotest/exemplary/simple-native.json new file mode 100644 index 0000000000..47a13e57e5 --- /dev/null +++ b/adapters/displayio/displayiotest/exemplary/simple-native.json @@ -0,0 +1,114 @@ +{ + "mockBidRequest": { + "app": { + "id": "1011" + }, + "id": "requestId10111011101110111011", + "imp": [ + { + "native": { + "request": "{\"ver\":\"1.1\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":50}},{\"id\":2,\"required\":0,\"data\":{\"type\":2,\"len\":100}},{\"id\":3,\"required\":1,\"img\":{\"type\":3,\"w\":480,\"h\":320}}]}", + "ver": "1.1" + }, + "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": [ + { + "native": { + "request": "{\"ver\":\"1.1\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":50}},{\"id\":2,\"required\":0,\"data\":{\"type\":2,\"len\":100}},{\"id\":3,\"required\":1,\"img\":{\"type\":3,\"w\":480,\"h\":320}}]}", + "ver": "1.1" + }, + "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" + ], + "mtype": 4 + } + ], + "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" + ], + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ 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 index be66747a4c..6b14653264 100644 --- a/adapters/displayio/displayiotest/supplemental/unexpected-media-type.json +++ b/adapters/displayio/displayiotest/supplemental/unexpected-media-type.json @@ -98,7 +98,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "unexpected media type for bid: .*", + "value": "unsupported MType .*", "comparison": "regex" } ] diff --git a/adapters/displayio/params_test.go b/adapters/displayio/params_test.go index 2e44954072..e11f1fadbc 100644 --- a/adapters/displayio/params_test.go +++ b/adapters/displayio/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/dmx/dmx.go b/adapters/dmx/dmx.go index 458b497826..e2389146d0 100644 --- a/adapters/dmx/dmx.go +++ b/adapters/dmx/dmx.go @@ -10,11 +10,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type DmxAdapter struct { diff --git a/adapters/dmx/dmx_test.go b/adapters/dmx/dmx_test.go index cc46d28f31..9e37d0e345 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/v3/adapters" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" - "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" ) func TestFetchParams(t *testing.T) { diff --git a/adapters/dmx/params_test.go b/adapters/dmx/params_test.go index 49d89b330f..6e2e2ba071 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/driftpixel/driftpixel.go b/adapters/driftpixel/driftpixel.go index 65532a786c..e62303ed8a 100644 --- a/adapters/driftpixel/driftpixel.go +++ b/adapters/driftpixel/driftpixel.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type bidType struct { diff --git a/adapters/driftpixel/driftpixel_test.go b/adapters/driftpixel/driftpixel_test.go index 24bf8b1506..11d5d604f9 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/driftpixel/params_test.go b/adapters/driftpixel/params_test.go index e8153f054c..225d949162 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/dxkulture/dxkulture.go b/adapters/dxkulture/dxkulture.go deleted file mode 100644 index 6b4bfa4003..0000000000 --- a/adapters/dxkulture/dxkulture.go +++ /dev/null @@ -1,172 +0,0 @@ -package dxkulture - -import ( - "encoding/json" - "fmt" - "net/http" - "net/url" - - "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" -) - -var markupTypeToBidType = map[openrtb2.MarkupType]openrtb_ext.BidType{ - openrtb2.MarkupBanner: openrtb_ext.BidTypeBanner, - openrtb2.MarkupVideo: openrtb_ext.BidTypeVideo, -} - -type adapter struct { - endpoint string -} - -// Builder builds a new instance of the DXKulture 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, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - impressions := request.Imp - - adapterRequests := make([]*adapters.RequestData, 0, len(impressions)) - var errs []error - - for _, impression := range impressions { - impExt, err := parseExt(&impression) - if err != nil { - errs = append(errs, err) - continue - } - - request.Imp = []openrtb2.Imp{impression} - body, err := json.Marshal(request) - if err != nil { - errs = append(errs, err) - continue - } - - if request.Test == 1 { - impExt.PublisherId = "test" - } - - params := url.Values{} - params.Add("publisher_id", impExt.PublisherId) - params.Add("placement_id", impExt.PlacementId) - - adapterRequests = append(adapterRequests, &adapters.RequestData{ - Method: http.MethodPost, - Uri: a.endpoint + "?" + params.Encode(), - Body: body, - Headers: getHeaders(request), - ImpIDs: openrtb_ext.GetImpIDs(request.Imp), - }) - } - - request.Imp = impressions - return adapterRequests, errs -} - -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 ortbResponse openrtb2.BidResponse - err := jsonutil.Unmarshal(response.Body, &ortbResponse) - if err != nil { - return nil, []error{&errortypes.BadServerResponse{ - Message: "Bad Server Response", - }} - } - - var bidErrors []error - - bidderResponse := adapters.NewBidderResponseWithBidsCapacity(1) - for _, seatBid := range ortbResponse.SeatBid { - for i := range seatBid.Bid { - bid := seatBid.Bid[i] - bidType, err := getBidType(&bid) - if err != nil { - bidErrors = append(bidErrors, err) - continue - } - - bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{ - Bid: &bid, - BidType: bidType, - }) - } - } - - return bidderResponse, bidErrors -} - -func getBidType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { - if bidType, ok := markupTypeToBidType[bid.MType]; ok { - return bidType, nil - } - return "", &errortypes.BadServerResponse{ - Message: fmt.Sprintf("Unsupported MType %d", bid.MType), - } -} - -func parseExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpDXKulture, error) { - var bidderExt adapters.ExtImpBidder - - 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 := 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), - } - } - - return &impExt, 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.Site != nil { - if request.Site.Ref != "" { - headers.Set("Referer", request.Site.Ref) - } - if request.Site.Domain != "" { - headers.Add("Origin", request.Site.Domain) - } - } - - 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 -} diff --git a/adapters/dxkulture/dxkulture_test.go b/adapters/dxkulture/dxkulture_test.go deleted file mode 100644 index 2ee176968b..0000000000 --- a/adapters/dxkulture/dxkulture_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package dxkulture - -import ( - "testing" - - "github.com/prebid/prebid-server/v3/config" - - "github.com/prebid/prebid-server/v3/adapters/adapterstest" -) - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder("dxkulture", config.Adapter{Endpoint: "https://ads.dxkulture.com/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, "dxkulturetest", bidder) -} diff --git a/adapters/dxkulture/dxkulturetest/exemplary/banner.json b/adapters/dxkulture/dxkulturetest/exemplary/banner.json deleted file mode 100644 index 6ae690bece..0000000000 --- a/adapters/dxkulture/dxkulturetest/exemplary/banner.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "method": "GET", - "headers": { - "Referer": [ - "http://site.com/ref" - ], - "Origin": [ - "site.com" - ], - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json;charset=utf-8" - ], - "User-Agent": [ - "user-agent" - ], - "X-Forwarded-For": [ - "1.2.3.4" - ], - "X-Openrtb-Version": [ - "2.5" - ] - }, - "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", - "body": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "cur": "USD", - "seatbid": [ - { - "bid": [ - { - "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", - "crid": "16329", - "adomain": [ - "adomain.com" - ], - "price": 3, - "impid": "test-imp-id", - "adid": "2422", - "adm": "", - "mtype": 1 - } - ], - "seat": "dxkulture" - } - ], - "bidid": "test-request-id", - "id": "test-request-id" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", - "crid": "16329", - "adomain": [ - "adomain.com" - ], - "price": 3, - "impid": "test-imp-id", - "adid": "2422", - "adm": "", - "mtype": 1 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/dxkulture/dxkulturetest/exemplary/empty-site-domain-ref.json b/adapters/dxkulture/dxkulturetest/exemplary/empty-site-domain-ref.json deleted file mode 100644 index 8c2408b291..0000000000 --- a/adapters/dxkulture/dxkulturetest/exemplary/empty-site-domain-ref.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "page": "http://site.com/page" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "method": "GET", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json;charset=utf-8" - ], - "User-Agent": [ - "user-agent" - ], - "X-Forwarded-For": [ - "1.2.3.4" - ], - "X-Openrtb-Version": [ - "2.5" - ] - }, - "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", - "body": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "page": "http://site.com/page" - } - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "cur": "USD", - "seatbid": [ - { - "bid": [ - { - "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", - "crid": "16329", - "adomain": [ - "adomain.com" - ], - "price": 3, - "impid": "test-imp-id", - "adid": "2422", - "adm": "", - "mtype": 2 - } - ], - "seat": "dxkulture" - } - ], - "bidid": "test-request-id", - "id": "test-request-id" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", - "crid": "16329", - "adomain": [ - "adomain.com" - ], - "price": 3, - "impid": "test-imp-id", - "adid": "2422", - "adm": "", - "mtype": 2 - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/dxkulture/dxkulturetest/exemplary/ipv6.json b/adapters/dxkulture/dxkulturetest/exemplary/ipv6.json deleted file mode 100644 index ca23591b92..0000000000 --- a/adapters/dxkulture/dxkulturetest/exemplary/ipv6.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ipv6": "2001:0000:130F:0000:0000:09C0:876A:130B" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "page": "http://site.com/page" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "method": "GET", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json;charset=utf-8" - ], - "User-Agent": [ - "user-agent" - ], - "X-Forwarded-For": [ - "2001:0000:130F:0000:0000:09C0:876A:130B" - ], - "X-Openrtb-Version": [ - "2.5" - ] - }, - "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", - "body": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ipv6": "2001:0000:130F:0000:0000:09C0:876A:130B" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "page": "http://site.com/page" - } - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "cur": "USD", - "seatbid": [ - { - "bid": [ - { - "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", - "crid": "16329", - "adomain": [ - "adomain.com" - ], - "price": 3, - "impid": "test-imp-id", - "adid": "2422", - "adm": "", - "mtype": 2 - } - ], - "seat": "dxkulture" - } - ], - "bidid": "test-request-id", - "id": "test-request-id" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", - "crid": "16329", - "adomain": [ - "adomain.com" - ], - "price": 3, - "impid": "test-imp-id", - "adid": "2422", - "adm": "", - "mtype": 2 - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/dxkulture/dxkulturetest/exemplary/video-test-request.json b/adapters/dxkulture/dxkulturetest/exemplary/video-test-request.json deleted file mode 100644 index 2b3599f942..0000000000 --- a/adapters/dxkulture/dxkulturetest/exemplary/video-test-request.json +++ /dev/null @@ -1,155 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "test": 1, - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "method": "GET", - "headers": { - "Referer": [ - "http://site.com/ref" - ], - "Origin": [ - "site.com" - ], - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json;charset=utf-8" - ], - "User-Agent": [ - "user-agent" - ], - "X-Forwarded-For": [ - "1.2.3.4" - ], - "X-Openrtb-Version": [ - "2.5" - ] - }, - "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=test", - "body": { - "id": "test-request-id", - "test": 1, - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "cur": "USD", - "seatbid": [ - { - "bid": [ - { - "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", - "crid": "16329", - "adomain": [ - "adomain.com" - ], - "price": 3, - "impid": "test-imp-id", - "adid": "2422", - "adm": "", - "mtype": 2 - } - ], - "seat": "dxkulture" - } - ], - "bidid": "test-request-id", - "id": "test-request-id" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", - "crid": "16329", - "adomain": [ - "adomain.com" - ], - "price": 3, - "impid": "test-imp-id", - "adid": "2422", - "adm": "", - "mtype": 2 - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/dxkulture/dxkulturetest/exemplary/video.json b/adapters/dxkulture/dxkulturetest/exemplary/video.json deleted file mode 100644 index b96fb107e3..0000000000 --- a/adapters/dxkulture/dxkulturetest/exemplary/video.json +++ /dev/null @@ -1,153 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "method": "GET", - "headers": { - "Referer": [ - "http://site.com/ref" - ], - "Origin": [ - "site.com" - ], - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json;charset=utf-8" - ], - "User-Agent": [ - "user-agent" - ], - "X-Forwarded-For": [ - "1.2.3.4" - ], - "X-Openrtb-Version": [ - "2.5" - ] - }, - "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", - "body": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "cur": "USD", - "seatbid": [ - { - "bid": [ - { - "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", - "crid": "16329", - "adomain": [ - "adomain.com" - ], - "price": 3, - "impid": "test-imp-id", - "adid": "2422", - "adm": "", - "mtype": 2 - } - ], - "seat": "dxkulture" - } - ], - "bidid": "test-request-id", - "id": "test-request-id" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", - "crid": "16329", - "adomain": [ - "adomain.com" - ], - "price": 3, - "impid": "test-imp-id", - "adid": "2422", - "adm": "", - "mtype": 2 - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext-bidder.json b/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext-bidder.json deleted file mode 100644 index c60c608057..0000000000 --- a/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext-bidder.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": "not_json" - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "expectedMakeRequestsErrors": [ - { - "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 deleted file mode 100644 index 379acd586c..0000000000 --- a/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": "not_json" - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "expectedMakeRequestsErrors": [ - { - "value": "Ignoring imp id=test-imp-id, error while decoding extImpBidder, err: expect { or n, but found \"", - "comparison": "literal" - } - ] -} diff --git a/adapters/dxkulture/dxkulturetest/supplemental/invalid-response.json b/adapters/dxkulture/dxkulturetest/supplemental/invalid-response.json deleted file mode 100644 index 40d18e6343..0000000000 --- a/adapters/dxkulture/dxkulturetest/supplemental/invalid-response.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "method": "GET", - "headers": { - "Referer": [ - "http://site.com/ref" - ], - "Origin": [ - "site.com" - ], - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json;charset=utf-8" - ], - "User-Agent": [ - "user-agent" - ], - "X-Forwarded-For": [ - "1.2.3.4" - ], - "X-Openrtb-Version": [ - "2.5" - ] - }, - "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", - "body": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": "body" - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "Bad Server Response", - "comparison": "literal" - } - ] -} diff --git a/adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json b/adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json deleted file mode 100644 index fe0f8a1202..0000000000 --- a/adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "method": "GET", - "headers": { - "Referer": [ - "http://site.com/ref" - ], - "Origin": [ - "site.com" - ], - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json;charset=utf-8" - ], - "User-Agent": [ - "user-agent" - ], - "X-Forwarded-For": [ - "1.2.3.4" - ], - "X-Openrtb-Version": [ - "2.5" - ] - }, - "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", - "body": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "cur": "USD", - "seatbid": [ - { - "bid": [ - { - "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", - "crid": "16329", - "adomain": [ - "adomain.com" - ], - "price": 3, - "impid": "test-imp-id", - "adid": "2422", - "adm": "" - } - ], - "seat": "dxkulture" - } - ], - "bidid": "test-request-id", - "id": "test-request-id" - } - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "Unsupported MType 0", - "comparison": "literal" - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [] - } - ] - -} diff --git a/adapters/dxkulture/dxkulturetest/supplemental/status-code-no-content.json b/adapters/dxkulture/dxkulturetest/supplemental/status-code-no-content.json deleted file mode 100644 index 75bae07d4f..0000000000 --- a/adapters/dxkulture/dxkulturetest/supplemental/status-code-no-content.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "method": "GET", - "headers": { - "Referer": [ - "http://site.com/ref" - ], - "Origin": [ - "site.com" - ], - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json;charset=utf-8" - ], - "User-Agent": [ - "user-agent" - ], - "X-Forwarded-For": [ - "1.2.3.4" - ], - "X-Openrtb-Version": [ - "2.5" - ] - }, - "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", - "body": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 1920, - "h": 1080, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisherId": "pub123", - "placementId": "placement123" - } - } - } - ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" - } - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 204 - } - } - ], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [] -} diff --git a/adapters/dxkulture/params_test.go b/adapters/dxkulture/params_test.go deleted file mode 100644 index c7997f1862..0000000000 --- a/adapters/dxkulture/params_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package dxkulture - -import ( - "encoding/json" - "testing" - - "github.com/prebid/prebid-server/v3/openrtb_ext" -) - -// This file actually intends to test static/bidder-params/dxkulture.json -// -// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.dxkulture - -// TestValidParams makes sure that the dxkulture 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.BidderDXKulture, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected dxkulture params: %s", validParam) - } - } -} - -// TestInvalidParams makes sure that the dxkulture 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.BidderDXKulture, json.RawMessage(invalidParam)); err == nil { - t.Errorf("Schema allowed unexpected params: %s", invalidParam) - } - } -} - -var validParams = []string{ - `{"publisherId": "pub", "placementId": "plac"}`, - `{"publisherId": "pub", "placementId": "plac", "a":1}`, -} - -var invalidParams = []string{ - `{"publisherId": "pub"}`, - `{"placementId": "plac"}`, - //malformed - `{"ub", "placementId": "plac"}`, - `{}`, -} diff --git a/adapters/e_volution/evolution.go b/adapters/e_volution/evolution.go index 1b781c7405..3db5173ca6 100644 --- a/adapters/e_volution/evolution.go +++ b/adapters/e_volution/evolution.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/e_volution/evolution_test.go b/adapters/e_volution/evolution_test.go index 6a3dbe671e..3a16856945 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/e_volution/params_test.go b/adapters/e_volution/params_test.go index 98558f88ab..ace2e32927 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/edge226/edge226.go b/adapters/edge226/edge226.go index 19804c8843..69f2b34646 100644 --- a/adapters/edge226/edge226.go +++ b/adapters/edge226/edge226.go @@ -6,10 +6,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/edge226/edge226_test.go b/adapters/edge226/edge226_test.go index cd3d9385ab..97927ef4c0 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/edge226/params_test.go b/adapters/edge226/params_test.go index 5161c349d7..9b5c210522 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adoppler/adoppler.go b/adapters/elementaltv/elementaltv.go similarity index 82% rename from adapters/adoppler/adoppler.go rename to adapters/elementaltv/elementaltv.go index ace52b93b1..4d84037b5c 100644 --- a/adapters/adoppler/adoppler.go +++ b/adapters/elementaltv/elementaltv.go @@ -1,28 +1,25 @@ -package adoppler +package elementaltv 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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) -const DefaultClient = "app" - var bidHeaders http.Header = map[string][]string{ "Accept": {"application/json"}, "Content-Type": {"application/json;charset=utf-8"}, - "X-OpenRTB-Version": {"2.5"}, + "X-OpenRTB-Version": {"2.6"}, } type adsVideoExt struct { @@ -33,24 +30,24 @@ type adsImpExt struct { Video *adsVideoExt `json:"video"` } -type AdopplerAdapter struct { +type adapter struct { endpoint *template.Template } -// Builder builds a new instance of the Adoppler adapter for the given bidder with the given config. +// Builder builds a new instance of the ElementalTV 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) + return nil, fmt.Errorf("unable to parse endpoint url template: %w", err) } - bidder := &AdopplerAdapter{ + bidder := &adapter{ endpoint: template, } return bidder, nil } -func (ads *AdopplerAdapter) MakeRequests( +func (ads *adapter) MakeRequests( req *openrtb2.BidRequest, info *adapters.ExtraRequestInfo, ) ( @@ -74,7 +71,7 @@ func (ads *AdopplerAdapter) MakeRequests( r.ID = req.ID + "-" + ext.AdUnit r.Imp = []openrtb2.Imp{imp} - body, err := json.Marshal(r) + body, err := jsonutil.Marshal(r) if err != nil { errs = append(errs, err) continue @@ -100,7 +97,7 @@ func (ads *AdopplerAdapter) MakeRequests( return datas, errs } -func (ads *AdopplerAdapter) MakeBids( +func (ads *adapter) MakeBids( intReq *openrtb2.BidRequest, extReq *adapters.RequestData, resp *adapters.ResponseData, @@ -193,33 +190,29 @@ func (ads *AdopplerAdapter) MakeBids( return adsResp, nil } -func (ads *AdopplerAdapter) bidUri(ext *openrtb_ext.ExtImpAdoppler) (string, error) { +func (ads *adapter) bidUri(ext *openrtb_ext.ExtImpElementalTV) (string, error) { params := macros.EndpointTemplateParams{} params.AdUnit = url.PathEscape(ext.AdUnit) - if ext.Client == "" { - params.AccountID = DefaultClient - } else { - params.AccountID = url.PathEscape(ext.Client) - } - return macros.ResolveMacros(ads.endpoint, params) } -func unmarshalExt(ext json.RawMessage) (*openrtb_ext.ExtImpAdoppler, error) { +func unmarshalExt(ext json.RawMessage) (*openrtb_ext.ExtImpElementalTV, error) { var bext adapters.ExtImpBidder err := jsonutil.Unmarshal(ext, &bext) if err != nil { return nil, err } - var adsExt openrtb_ext.ExtImpAdoppler + var adsExt openrtb_ext.ExtImpElementalTV err = jsonutil.Unmarshal(bext.Bidder, &adsExt) if err != nil { return nil, err } if adsExt.AdUnit == "" { - return nil, errors.New("$.imp.ext.adoppler.adunit required") + return nil, &errortypes.BadInput{ + Message: "$.imp.ext.bidder.adunit required", + } } return &adsExt, nil diff --git a/adapters/elementaltv/elementaltv_test.go b/adapters/elementaltv/elementaltv_test.go new file mode 100644 index 0000000000..c54c8c1570 --- /dev/null +++ b/adapters/elementaltv/elementaltv_test.go @@ -0,0 +1,19 @@ +package elementaltv + +import ( + "testing" + + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/require" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderElementalTV, config.Adapter{ + Endpoint: "https://pbs.elementaltv.io/processHeaderBid/{{.AdUnit}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + require.NoError(t, buildErr, "Builder returned unexpected error") + + adapterstest.RunJSONBidderTest(t, "elementaltvtest", bidder) +} diff --git a/adapters/adoppler/adopplertest/exemplary/default-client.json b/adapters/elementaltv/elementaltvtest/exemplary/base.json similarity index 95% rename from adapters/adoppler/adopplertest/exemplary/default-client.json rename to adapters/elementaltv/elementaltvtest/exemplary/base.json index dd53208f7d..b7913c6597 100644 --- a/adapters/adoppler/adopplertest/exemplary/default-client.json +++ b/adapters/elementaltv/elementaltvtest/exemplary/base.json @@ -19,7 +19,7 @@ "httpCalls":[ { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit1", "body":{ "id":"req1-unit1", "imp":[ diff --git a/adapters/adoppler/adopplertest/exemplary/multiimp.json b/adapters/elementaltv/elementaltvtest/exemplary/multiimp.json similarity index 95% rename from adapters/adoppler/adopplertest/exemplary/multiimp.json rename to adapters/elementaltv/elementaltvtest/exemplary/multiimp.json index bdbef5a4af..6575a50300 100644 --- a/adapters/adoppler/adopplertest/exemplary/multiimp.json +++ b/adapters/elementaltv/elementaltvtest/exemplary/multiimp.json @@ -44,7 +44,7 @@ "httpCalls":[ { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit1", "body":{ "id":"req1-unit1", "imp":[ @@ -86,7 +86,7 @@ }, { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit2", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit2", "body":{ "id":"req1-unit2", "imp":[ @@ -141,7 +141,7 @@ }, { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit3", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit3", "body":{ "id":"req1-unit3", "imp":[ diff --git a/adapters/adoppler/adopplertest/supplemental/bad-request.json b/adapters/elementaltv/elementaltvtest/supplemental/bad-request.json similarity index 92% rename from adapters/adoppler/adopplertest/supplemental/bad-request.json rename to adapters/elementaltv/elementaltvtest/supplemental/bad-request.json index c2e3846020..3fac885c8a 100644 --- a/adapters/adoppler/adopplertest/supplemental/bad-request.json +++ b/adapters/elementaltv/elementaltvtest/supplemental/bad-request.json @@ -19,7 +19,7 @@ "httpCalls":[ { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit1", "body":{ "id":"req1-unit1", "imp":[ diff --git a/adapters/adoppler/adopplertest/supplemental/duplicate-imp.json b/adapters/elementaltv/elementaltvtest/supplemental/duplicate-imp.json similarity index 94% rename from adapters/adoppler/adopplertest/supplemental/duplicate-imp.json rename to adapters/elementaltv/elementaltvtest/supplemental/duplicate-imp.json index cc24ae03a2..137997c2ce 100644 --- a/adapters/adoppler/adopplertest/supplemental/duplicate-imp.json +++ b/adapters/elementaltv/elementaltvtest/supplemental/duplicate-imp.json @@ -31,7 +31,7 @@ "httpCalls":[ { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit1", "body":{ "id":"req1-unit1", "imp":[ @@ -73,7 +73,7 @@ }, { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit2", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit2", "body":{ "id":"req1-unit2", "imp":[ diff --git a/adapters/adoppler/adopplertest/supplemental/invalid-impid.json b/adapters/elementaltv/elementaltvtest/supplemental/invalid-impid.json similarity index 94% rename from adapters/adoppler/adopplertest/supplemental/invalid-impid.json rename to adapters/elementaltv/elementaltvtest/supplemental/invalid-impid.json index e94a0e0c40..2ea9ed4c32 100644 --- a/adapters/adoppler/adopplertest/supplemental/invalid-impid.json +++ b/adapters/elementaltv/elementaltvtest/supplemental/invalid-impid.json @@ -19,7 +19,7 @@ "httpCalls":[ { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit1", "body":{ "id":"req1-unit1", "imp":[ diff --git a/adapters/adoppler/adopplertest/supplemental/invalid-response.json b/adapters/elementaltv/elementaltvtest/supplemental/invalid-response.json similarity index 92% rename from adapters/adoppler/adopplertest/supplemental/invalid-response.json rename to adapters/elementaltv/elementaltvtest/supplemental/invalid-response.json index 84342feaa0..81c9ba5968 100644 --- a/adapters/adoppler/adopplertest/supplemental/invalid-response.json +++ b/adapters/elementaltv/elementaltvtest/supplemental/invalid-response.json @@ -19,7 +19,7 @@ "httpCalls":[ { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit1", "body":{ "id":"req1-unit1", "imp":[ diff --git a/adapters/adoppler/adopplertest/supplemental/invalid-video-ext.json b/adapters/elementaltv/elementaltvtest/supplemental/invalid-video-ext.json similarity index 95% rename from adapters/adoppler/adopplertest/supplemental/invalid-video-ext.json rename to adapters/elementaltv/elementaltvtest/supplemental/invalid-video-ext.json index 6bab4036c5..8f3386c138 100644 --- a/adapters/adoppler/adopplertest/supplemental/invalid-video-ext.json +++ b/adapters/elementaltv/elementaltvtest/supplemental/invalid-video-ext.json @@ -35,7 +35,7 @@ "httpCalls":[ { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit1", "body":{ "id":"req1-unit1", "imp":[ @@ -86,7 +86,7 @@ }, { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit2", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit2", "body":{ "id":"req1-unit2", "imp":[ diff --git a/adapters/adoppler/adopplertest/supplemental/missing-adunit.json b/adapters/elementaltv/elementaltvtest/supplemental/missing-adunit.json similarity index 87% rename from adapters/adoppler/adopplertest/supplemental/missing-adunit.json rename to adapters/elementaltv/elementaltvtest/supplemental/missing-adunit.json index df9bbe5771..92ff8a25eb 100644 --- a/adapters/adoppler/adopplertest/supplemental/missing-adunit.json +++ b/adapters/elementaltv/elementaltvtest/supplemental/missing-adunit.json @@ -24,7 +24,7 @@ ], "expectedMakeRequestsErrors":[ { - "value":"$.imp.ext.adoppler.adunit required", + "value":"$.imp.ext.bidder.adunit required", "comparison":"literal" } ] diff --git a/adapters/adoppler/adopplertest/supplemental/no-bid.json b/adapters/elementaltv/elementaltvtest/supplemental/no-bid.json similarity index 91% rename from adapters/adoppler/adopplertest/supplemental/no-bid.json rename to adapters/elementaltv/elementaltvtest/supplemental/no-bid.json index 9135b4c5f2..6f8099516b 100644 --- a/adapters/adoppler/adopplertest/supplemental/no-bid.json +++ b/adapters/elementaltv/elementaltvtest/supplemental/no-bid.json @@ -19,7 +19,7 @@ "httpCalls":[ { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit1", "body":{ "id":"req1-unit1", "imp":[ diff --git a/adapters/adoppler/adopplertest/supplemental/server-error.json b/adapters/elementaltv/elementaltvtest/supplemental/server-error.json similarity index 92% rename from adapters/adoppler/adopplertest/supplemental/server-error.json rename to adapters/elementaltv/elementaltvtest/supplemental/server-error.json index dcd45e3718..5341d2473a 100644 --- a/adapters/adoppler/adopplertest/supplemental/server-error.json +++ b/adapters/elementaltv/elementaltvtest/supplemental/server-error.json @@ -19,7 +19,7 @@ "httpCalls":[ { "expectedRequest":{ - "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "uri":"https://pbs.elementaltv.io/processHeaderBid/unit1", "body":{ "id":"req1-unit1", "imp":[ diff --git a/adapters/elementaltv/params_test.go b/adapters/elementaltv/params_test.go new file mode 100644 index 0000000000..0c49095ca1 --- /dev/null +++ b/adapters/elementaltv/params_test.go @@ -0,0 +1,38 @@ +package elementaltv + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/require" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + require.NoErrorf(t, err, "Failed to fetch the json schema: %v", err) + for _, p := range validParams { + err := validator.Validate(openrtb_ext.BidderElementalTV, json.RawMessage(p)) + require.NoError(t, err, "Schema rejected valid params: %s", p) + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + require.NoErrorf(t, err, "Failed to fetch the json schema: %v", err) + + for _, p := range invalidParams { + err := validator.Validate(openrtb_ext.BidderElementalTV, json.RawMessage(p)) + require.Error(t, err, "Schema allowed invalid params: %s", p) + } +} + +var validParams = []string{ + `{"adunit":"123"}`, + `{"adunit":"SSP:123"}`, + `{"adunit":"5346"}`} + +var invalidParams = []string{ + `{}`, + `{"adunitt":"123"}`, +} diff --git a/adapters/emtv/emtv.go b/adapters/emtv/emtv.go index c8814f8065..678c4bddca 100644 --- a/adapters/emtv/emtv.go +++ b/adapters/emtv/emtv.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/emtv/emtv_test.go b/adapters/emtv/emtv_test.go index 0dd4196af4..d2c36b2ae8 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/emtv/params_test.go b/adapters/emtv/params_test.go index cdea31b075..13631f3bb1 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/eplanning/eplanning.go b/adapters/eplanning/eplanning.go index fe05fee008..c7ba971586 100644 --- a/adapters/eplanning/eplanning.go +++ b/adapters/eplanning/eplanning.go @@ -12,11 +12,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "strconv" ) diff --git a/adapters/eplanning/eplanning_test.go b/adapters/eplanning/eplanning_test.go index 1d220184c6..3457b0023c 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/epom/epom.go b/adapters/epom/epom.go index 82e44b409e..077cd2ba93 100644 --- a/adapters/epom/epom.go +++ b/adapters/epom/epom.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/epom/epom_test.go b/adapters/epom/epom_test.go index f90f2189d5..78f8ba428e 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/escalax/escalax.go b/adapters/escalax/escalax.go index 867524a922..d11eea8f27 100644 --- a/adapters/escalax/escalax.go +++ b/adapters/escalax/escalax.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/escalax/escalax_test.go b/adapters/escalax/escalax_test.go index c4424bb10a..8d7ffcd0ee 100644 --- a/adapters/escalax/escalax_test.go +++ b/adapters/escalax/escalax_test.go @@ -3,9 +3,9 @@ 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/escalax/params_test.go b/adapters/escalax/params_test.go index 6e6036721a..93e605612e 100644 --- a/adapters/escalax/params_test.go +++ b/adapters/escalax/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/eskimi/eskimi.go b/adapters/eskimi/eskimi.go new file mode 100644 index 0000000000..0f6b3e7fd0 --- /dev/null +++ b/adapters/eskimi/eskimi.go @@ -0,0 +1,259 @@ +package eskimi + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/adcom1" + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Eskimi 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 +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + if len(request.Imp) == 0 { + return nil, []error{&errortypes.BadInput{Message: "no impressions in the bid request"}} + } + + outgoing := *request + outgoing.Imp = append([]openrtb2.Imp(nil), request.Imp...) + + first, err := parseImpExt(outgoing.Imp[0]) + if err != nil { + return nil, []error{err} + } + + if err := setPlacementID(&outgoing, first.PlacementID); err != nil { + return nil, []error{err} + } + + applyRequestParams(&outgoing, first) + + // Imps whose ext fails to parse are dropped so malformed data is never + // forwarded upstream; the parse error is still reported to the caller. + imps := make([]openrtb2.Imp, 0, len(outgoing.Imp)) + impExts := make([]*openrtb_ext.ExtImpEskimi, 0, len(outgoing.Imp)) + imps = append(imps, outgoing.Imp[0]) + impExts = append(impExts, &first) + var errs []error + for i := 1; i < len(outgoing.Imp); i++ { + ext, perr := parseImpExt(outgoing.Imp[i]) + if perr != nil { + errs = append(errs, perr) + continue + } + imps = append(imps, outgoing.Imp[i]) + impExts = append(impExts, &ext) + } + outgoing.Imp = imps + + applyImpParams(&outgoing, impExts) + + body, err := jsonutil.Marshal(&outgoing) + if err != nil { + return nil, append(errs, 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: body, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(outgoing.Imp), + }}, errs +} + +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} + } + + var errs []error + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if response.Cur != "" { + bidResponse.Currency = response.Cur + } + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bidType, typeErr := getMediaTypeForBid(request.Imp, seatBid.Bid[i]) + if typeErr != nil { + errs = append(errs, typeErr) + continue + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + }) + } + } + return bidResponse, errs +} + +func parseImpExt(imp openrtb2.Imp) (openrtb_ext.ExtImpEskimi, error) { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return openrtb_ext.ExtImpEskimi{}, &errortypes.BadInput{Message: fmt.Sprintf("invalid imp.ext for imp %s: %s", imp.ID, err)} + } + var eskimiExt openrtb_ext.ExtImpEskimi + if err := jsonutil.Unmarshal(bidderExt.Bidder, &eskimiExt); err != nil { + return openrtb_ext.ExtImpEskimi{}, &errortypes.BadInput{Message: fmt.Sprintf("invalid imp.ext.bidder for imp %s: %s", imp.ID, err)} + } + return eskimiExt, nil +} + +// setPlacementID writes the placement ID to site.ext.placementId or app.ext.placementId, +// preserving any other existing keys in the ext object. +func setPlacementID(request *openrtb2.BidRequest, placementID int64) error { + patch := func(ext json.RawMessage) (json.RawMessage, error) { + fields := map[string]json.RawMessage{} + if len(ext) > 0 { + if err := jsonutil.Unmarshal(ext, &fields); err != nil { + return nil, err + } + } + id, err := jsonutil.Marshal(placementID) + if err != nil { + return nil, err + } + fields["placementId"] = id + return jsonutil.Marshal(fields) + } + + switch { + case request.Site != nil: + site := *request.Site + ext, err := patch(site.Ext) + if err != nil { + return &errortypes.BadInput{Message: fmt.Sprintf("failed to set placementId on site.ext: %s", err)} + } + site.Ext = ext + request.Site = &site + case request.App != nil: + app := *request.App + ext, err := patch(app.Ext) + if err != nil { + return &errortypes.BadInput{Message: fmt.Sprintf("failed to set placementId on app.ext: %s", err)} + } + app.Ext = ext + request.App = &app + default: + return &errortypes.BadInput{Message: "request must contain either site or app"} + } + return nil +} + +// applyRequestParams promotes request-level blocklists from the first imp's bidder ext +// when the request doesn't already set them. Existing publisher/wrapper values win. +func applyRequestParams(request *openrtb2.BidRequest, ext openrtb_ext.ExtImpEskimi) { + if len(request.BCat) == 0 && len(ext.Bcat) > 0 { + request.BCat = ext.Bcat + } + if len(request.BAdv) == 0 && len(ext.Badv) > 0 { + request.BAdv = ext.Badv + } + if len(request.BApp) == 0 && len(ext.Bapp) > 0 { + request.BApp = ext.Bapp + } +} + +// applyImpParams applies per-imp params from the bidder ext: defaults imp.secure to 1, +// fills bid floor when unset, and fans out battr to both banner.battr and video.battr. +func applyImpParams(request *openrtb2.BidRequest, exts []*openrtb_ext.ExtImpEskimi) { + for i := range request.Imp { + if request.Imp[i].Secure == nil { + s := int8(1) + request.Imp[i].Secure = &s + } + ext := exts[i] + if ext == nil { + continue + } + if request.Imp[i].BidFloor == 0 && ext.BidFloor > 0 { + request.Imp[i].BidFloor = ext.BidFloor + if ext.BidFloorCur != "" { + request.Imp[i].BidFloorCur = ext.BidFloorCur + } + } + if len(ext.Battr) > 0 { + attrs := make([]adcom1.CreativeAttribute, len(ext.Battr)) + for j, v := range ext.Battr { + attrs[j] = adcom1.CreativeAttribute(v) + } + if request.Imp[i].Banner != nil && len(request.Imp[i].Banner.BAttr) == 0 { + banner := *request.Imp[i].Banner + banner.BAttr = attrs + request.Imp[i].Banner = &banner + } + if request.Imp[i].Video != nil && len(request.Imp[i].Video.BAttr) == 0 { + video := *request.Imp[i].Video + video.BAttr = attrs + request.Imp[i].Video = &video + } + } + } +} + +// getMediaTypeForBid resolves the bid's media type. When bid.mtype is set it is treated +// as authoritative; an unsupported value returns an error rather than falling back to +// imp inference. When bid.mtype is unset, the imp's media type is used; multi-format +// imps without mtype cannot be disambiguated and return an error. +func getMediaTypeForBid(imps []openrtb2.Imp, bid openrtb2.Bid) (openrtb_ext.BidType, error) { + if bid.MType != 0 { + 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 bid.mtype %d for impression %s (banner and video only)", bid.MType, bid.ImpID), + } + } + } + for _, imp := range imps { + if imp.ID != bid.ImpID { + continue + } + switch { + case imp.Banner != nil && imp.Video == nil: + return openrtb_ext.BidTypeBanner, nil + case imp.Video != nil && imp.Banner == nil: + return openrtb_ext.BidTypeVideo, nil + case imp.Banner != nil && imp.Video != nil: + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("bid for multi-format imp %s requires bid.mtype to disambiguate", bid.ImpID), + } + } + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("unsupported media type for impression %s (banner and video only)", bid.ImpID), + } + } + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("unable to resolve media type for impression %s", bid.ImpID), + } +} diff --git a/adapters/eskimi/eskimi_test.go b/adapters/eskimi/eskimi_test.go new file mode 100644 index 0000000000..c40f0bff3b --- /dev/null +++ b/adapters/eskimi/eskimi_test.go @@ -0,0 +1,157 @@ +package eskimi + +import ( + "encoding/json" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +const testEndpoint = "https://ittr.eskimi.com/prebidjs" + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderEskimi, config.Adapter{ + Endpoint: testEndpoint}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 814, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "eskimitest", bidder) +} + +func newAdapter() *adapter { + return &adapter{endpoint: testEndpoint} +} + +func bannerImp(ext string) openrtb2.Imp { + return openrtb2.Imp{ + ID: "imp-1", + Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}, + Ext: json.RawMessage(ext), + } +} + +func TestMalformedSiteExt(t *testing.T) { + req := &openrtb2.BidRequest{ + ID: "req-1", + Imp: []openrtb2.Imp{bannerImp(`{"bidder":{"placementId":625}}`)}, + Site: &openrtb2.Site{ID: "271", Ext: json.RawMessage(`{invalid`)}, + } + _, errs := newAdapter().MakeRequests(req, &adapters.ExtraRequestInfo{}) + assert.Len(t, errs, 1) + assert.Contains(t, errs[0].Error(), "site.ext") +} + +func TestMalformedAppExt(t *testing.T) { + req := &openrtb2.BidRequest{ + ID: "req-1", + Imp: []openrtb2.Imp{bannerImp(`{"bidder":{"placementId":625}}`)}, + App: &openrtb2.App{ID: "app-1", Ext: json.RawMessage(`{invalid`)}, + } + _, errs := newAdapter().MakeRequests(req, &adapters.ExtraRequestInfo{}) + assert.Len(t, errs, 1) + assert.Contains(t, errs[0].Error(), "app.ext") +} + +func TestImpSecureDefaultedToOne(t *testing.T) { + req := &openrtb2.BidRequest{ + ID: "req-1", + Imp: []openrtb2.Imp{bannerImp(`{"bidder":{"placementId":625}}`)}, + Site: &openrtb2.Site{ID: "271"}, + } + reqData, errs := newAdapter().MakeRequests(req, &adapters.ExtraRequestInfo{}) + assert.Empty(t, errs) + var out openrtb2.BidRequest + assert.NoError(t, json.Unmarshal(reqData[0].Body, &out)) + assert.NotNil(t, out.Imp[0].Secure) + assert.EqualValues(t, 1, *out.Imp[0].Secure) +} + +func TestImpSecureNotOverridden(t *testing.T) { + zero := int8(0) + imp := bannerImp(`{"bidder":{"placementId":625}}`) + imp.Secure = &zero + req := &openrtb2.BidRequest{ + ID: "req-1", + Imp: []openrtb2.Imp{imp}, + Site: &openrtb2.Site{ID: "271"}, + } + reqData, errs := newAdapter().MakeRequests(req, &adapters.ExtraRequestInfo{}) + assert.Empty(t, errs) + var out openrtb2.BidRequest + assert.NoError(t, json.Unmarshal(reqData[0].Body, &out)) + assert.EqualValues(t, 0, *out.Imp[0].Secure) +} + +// TestCallerRequestNotMutated asserts every copy-on-write surface in MakeRequests: +// request.{BCat,BAdv,BApp}, request.{Site,App}.Ext, request.Imp[i].Secure, +// request.Imp[i].{Banner,Video}.BAttr, and request.Imp[i].{BidFloor,BidFloorCur}. +func TestCallerRequestNotMutated(t *testing.T) { + imp := openrtb2.Imp{ + ID: "imp-1", + Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}, + Video: &openrtb2.Video{MIMEs: []string{"video/mp4"}, W: openrtb2.Int64Ptr(640), H: openrtb2.Int64Ptr(480)}, + Ext: json.RawMessage(`{"bidder":{ + "placementId":625, + "bcat":["IAB1"],"badv":["bad.com"],"bapp":["com.bad"], + "bidFloor":1.5,"bidFloorCur":"EUR", + "battr":[1,2] + }}`), + } + req := &openrtb2.BidRequest{ + ID: "req-1", + Imp: []openrtb2.Imp{imp}, + Site: &openrtb2.Site{ID: "271", Ext: json.RawMessage(`{"amp":0}`)}, + } + + _, errs := newAdapter().MakeRequests(req, &adapters.ExtraRequestInfo{}) + assert.Empty(t, errs) + + assert.Empty(t, req.BCat, "caller's request.BCat must not be mutated") + assert.Empty(t, req.BAdv, "caller's request.BAdv must not be mutated") + assert.Empty(t, req.BApp, "caller's request.BApp must not be mutated") + assert.JSONEq(t, `{"amp":0}`, string(req.Site.Ext), "caller's request.Site.Ext must not be mutated") + assert.Nil(t, req.Imp[0].Secure, "caller's imp[0].Secure must not be mutated") + assert.EqualValues(t, 0, req.Imp[0].BidFloor, "caller's imp[0].BidFloor must not be mutated") + assert.Empty(t, req.Imp[0].BidFloorCur, "caller's imp[0].BidFloorCur must not be mutated") + assert.Empty(t, req.Imp[0].Banner.BAttr, "caller's imp[0].Banner.BAttr must not be mutated") + assert.Empty(t, req.Imp[0].Video.BAttr, "caller's imp[0].Video.BAttr must not be mutated") +} + +func TestCallerAppRequestNotMutated(t *testing.T) { + req := &openrtb2.BidRequest{ + ID: "req-1", + Imp: []openrtb2.Imp{bannerImp(`{"bidder":{"placementId":625}}`)}, + App: &openrtb2.App{ID: "app-1", Ext: json.RawMessage(`{"installed":1}`)}, + } + _, errs := newAdapter().MakeRequests(req, &adapters.ExtraRequestInfo{}) + assert.Empty(t, errs) + assert.JSONEq(t, `{"installed":1}`, string(req.App.Ext), "caller's request.App.Ext must not be mutated") +} + +func TestLaterImpWithInvalidExtSurfacesError(t *testing.T) { + req := &openrtb2.BidRequest{ + ID: "req-1", + Imp: []openrtb2.Imp{ + bannerImp(`{"bidder":{"placementId":625,"bidFloor":1.5,"bidFloorCur":"EUR"}}`), + {ID: "imp-2", Banner: &openrtb2.Banner{}, Ext: json.RawMessage(`"not-an-object"`)}, + }, + Site: &openrtb2.Site{ID: "271"}, + } + reqData, errs := newAdapter().MakeRequests(req, &adapters.ExtraRequestInfo{}) + // First-imp request still goes out, but the bad later imp surfaces an error. + assert.Len(t, errs, 1) + assert.Contains(t, errs[0].Error(), "imp.ext") + assert.Len(t, reqData, 1) + + var out openrtb2.BidRequest + assert.NoError(t, json.Unmarshal(reqData[0].Body, &out)) + assert.EqualValues(t, 1.5, out.Imp[0].BidFloor) +} diff --git a/adapters/eskimi/eskimitest/exemplary/banner-web-with-buyeruid.json b/adapters/eskimi/eskimitest/exemplary/banner-web-with-buyeruid.json new file mode 100644 index 0000000000..f8a3421e8b --- /dev/null +++ b/adapters/eskimi/eskimitest/exemplary/banner-web-with-buyeruid.json @@ -0,0 +1,94 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { + "bidder": { + "placementId": 625 + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com" + }, + "user": { + "buyeruid": "eskimi-dmp-id-abc-123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + }, + "user": { + "buyeruid": "eskimi-dmp-id-abc-123" + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { + "id": "1", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
ad
", + "crid": "creative-1", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
ad
", + "crid": "creative-1", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/exemplary/multi-imp-web.json b/adapters/eskimi/eskimitest/exemplary/multi-imp-web.json new file mode 100644 index 0000000000..f782fb730f --- /dev/null +++ b/adapters/eskimi/eskimitest/exemplary/multi-imp-web.json @@ -0,0 +1,162 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "imp-banner", + "banner": { + "format": [ + { "w": 300, "h": 250 } + ] + }, + "ext": { + "bidder": { + "placementId": 625 + } + } + }, + { + "id": "imp-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8], + "plcmt": 1 + }, + "ext": { + "bidder": { + "placementId": 999 + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "page": "https://display.eskimi-creatives.com/" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"] + }, + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "imp-banner", + "secure": 1, + "banner": { + "format": [ + { "w": 300, "h": 250 } + ] + }, + "ext": { + "bidder": { + "placementId": 625 + } + } + }, + { + "id": "imp-video", + "secure": 1, + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8], + "plcmt": 1 + }, + "ext": { + "bidder": { + "placementId": 999 + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "page": "https://display.eskimi-creatives.com/", + "ext": { + "placementId": 625 + } + } + }, + "impIDs": ["imp-banner", "imp-video"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { + "id": "1", + "impid": "imp-banner", + "price": 1.25, + "adm": "
ad
", + "crid": "creative-1", + "w": 300, + "h": 250, + "mtype": 1 + }, + { + "id": "2", + "impid": "imp-video", + "price": 4.5, + "adm": "00:00:15", + "crid": "video-creative-1", + "w": 640, + "h": 480, + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "imp-banner", + "price": 1.25, + "adm": "
ad
", + "crid": "creative-1", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "2", + "impid": "imp-video", + "price": 4.5, + "adm": "00:00:15", + "crid": "video-creative-1", + "w": 640, + "h": 480, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/exemplary/optional-params.json b/adapters/eskimi/eskimitest/exemplary/optional-params.json new file mode 100644 index 0000000000..350900008c --- /dev/null +++ b/adapters/eskimi/eskimitest/exemplary/optional-params.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { "w": 300, "h": 250 } + ] + }, + "ext": { + "bidder": { + "placementId": 625, + "bidFloor": 1.5, + "bidFloorCur": "EUR", + "bcat": ["IAB1"], + "badv": ["bad.com"], + "bapp": ["com.bad.app"], + "battr": [1, 2] + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "bcat": ["IAB1"], + "badv": ["bad.com"], + "bapp": ["com.bad.app"], + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "bidfloor": 1.5, + "bidfloorcur": "EUR", + "banner": { + "format": [ + { "w": 300, "h": 250 } + ], + "battr": [1, 2] + }, + "ext": { + "bidder": { + "placementId": 625, + "bidFloor": 1.5, + "bidFloorCur": "EUR", + "bcat": ["IAB1"], + "badv": ["bad.com"], + "bapp": ["com.bad.app"], + "battr": [1, 2] + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { + "placementId": 625 + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { + "id": "1", + "impid": "test-imp-id", + "price": 2.0, + "adm": "
ad
", + "crid": "creative-1", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "test-imp-id", + "price": 2.0, + "adm": "
ad
", + "crid": "creative-1", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/exemplary/simple-banner-app.json b/adapters/eskimi/eskimitest/exemplary/simple-banner-app.json new file mode 100644 index 0000000000..b8a209f2c0 --- /dev/null +++ b/adapters/eskimi/eskimitest/exemplary/simple-banner-app.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { "w": 320, "h": 50 } + ] + }, + "ext": { + "bidder": { + "placementId": 625 + } + } + } + ], + "app": { + "id": "app-1", + "bundle": "com.eskimi.example", + "name": "Example App" + }, + "device": { + "ifa": "00000000-0000-0000-0000-000000000000", + "os": "Android" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { + "format": [ + { "w": 320, "h": 50 } + ] + }, + "ext": { + "bidder": { + "placementId": 625 + } + } + } + ], + "app": { + "id": "app-1", + "bundle": "com.eskimi.example", + "name": "Example App", + "ext": { + "placementId": 625 + } + }, + "device": { + "ifa": "00000000-0000-0000-0000-000000000000", + "os": "Android" + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { + "id": "1", + "impid": "test-imp-id", + "price": 0.9, + "adm": "
ad
", + "crid": "creative-1", + "w": 320, + "h": 50, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "test-imp-id", + "price": 0.9, + "adm": "
ad
", + "crid": "creative-1", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/intertech/intertechtest/supplemental/no-device.json b/adapters/eskimi/eskimitest/exemplary/simple-banner-web.json similarity index 50% rename from adapters/intertech/intertechtest/supplemental/no-device.json rename to adapters/eskimi/eskimitest/exemplary/simple-banner-web.json index 8f811e0709..44cb835683 100644 --- a/adapters/intertech/intertechtest/supplemental/no-device.json +++ b/adapters/eskimi/eskimitest/exemplary/simple-banner-web.json @@ -1,76 +1,75 @@ { "mockBidRequest": { - "id": "test-request-no-device", - "site": { - "page": "mypage" - }, + "id": "test-request-id", "imp": [ { "id": "test-imp-id", - "tagid": "test-tag", "banner": { - "w": 300, - "h": 250 + "format": [ + { "w": 300, "h": 250 } + ] }, "ext": { "bidder": { - "page_id": 1001, - "imp_id": 2002 + "placementId": 625 } } } ], - "cur": ["USD"] + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "page": "https://display.eskimi-creatives.com/" + } }, "httpCalls": [ { "expectedRequest": { - "uri": "https://test.intertech.com/ssp?pid=1001&imp=2002&target-ref=mypage&ssp-cur=USD", - "headers": { - "Content-Type": ["application/json;charset=utf-8"], - "Accept": ["application/json"] - }, + "uri": "https://ittr.eskimi.com/prebidjs", "body": { - "id": "test-request-no-device", + "id": "test-request-id", "imp": [ { "id": "test-imp-id", - "tagid": "test-tag", + "secure": 1, "banner": { - "w": 300, - "h": 250 + "format": [ + { "w": 300, "h": 250 } + ] }, "ext": { "bidder": { - "page_id": 1001, - "imp_id": 2002 + "placementId": 625 } } } ], "site": { - "page": "mypage" - }, - "cur": ["USD"] + "id": "271", + "domain": "display.eskimi-creatives.com", + "page": "https://display.eskimi-creatives.com/", + "ext": { + "placementId": 625 + } + } }, "impIDs": ["test-imp-id"] }, "mockResponse": { "status": 200, "body": { - "id": "test-request-no-device", + "id": "test-request-id", "cur": "USD", "seatbid": [ { - "seat": "intertech", + "seat": "eskimi", "bid": [ { - "id": "test_bid_id", + "id": "1", "impid": "test-imp-id", - "price": 0.5, - "adm": "

Test Ad

", - "cid": "test_cid", - "crid": "test_crid", + "price": 1.25, + "adm": "
ad
", + "crid": "creative-1", "w": 300, "h": 250, "mtype": 1 @@ -84,15 +83,15 @@ ], "expectedBidResponses": [ { + "currency": "USD", "bids": [ { "bid": { - "id": "test_bid_id", + "id": "1", "impid": "test-imp-id", - "price": 0.5, - "adm": "

Test Ad

", - "cid": "test_cid", - "crid": "test_crid", + "price": 1.25, + "adm": "
ad
", + "crid": "creative-1", "w": 300, "h": 250, "mtype": 1 diff --git a/adapters/eskimi/eskimitest/exemplary/simple-video-app.json b/adapters/eskimi/eskimitest/exemplary/simple-video-app.json new file mode 100644 index 0000000000..cafcbde9cc --- /dev/null +++ b/adapters/eskimi/eskimitest/exemplary/simple-video-app.json @@ -0,0 +1,116 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8], + "plcmt": 1 + }, + "ext": { + "bidder": { + "placementId": 625 + } + } + } + ], + "app": { + "id": "app-1", + "bundle": "com.eskimi.example", + "name": "Example App" + }, + "device": { + "ifa": "00000000-0000-0000-0000-000000000000", + "os": "Android" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8], + "plcmt": 1 + }, + "ext": { + "bidder": { + "placementId": 625 + } + } + } + ], + "app": { + "id": "app-1", + "bundle": "com.eskimi.example", + "name": "Example App", + "ext": { + "placementId": 625 + } + }, + "device": { + "ifa": "00000000-0000-0000-0000-000000000000", + "os": "Android" + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { + "id": "1", + "impid": "test-imp-id", + "price": 5.25, + "nurl": "https://eskimi.com/win?bid=abc", + "crid": "video-creative-1", + "w": 640, + "h": 480, + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "test-imp-id", + "price": 5.25, + "nurl": "https://eskimi.com/win?bid=abc", + "crid": "video-creative-1", + "w": 640, + "h": 480, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/exemplary/simple-video-web.json b/adapters/eskimi/eskimitest/exemplary/simple-video-web.json new file mode 100644 index 0000000000..1dff5d1adc --- /dev/null +++ b/adapters/eskimi/eskimitest/exemplary/simple-video-web.json @@ -0,0 +1,108 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8], + "plcmt": 1 + }, + "ext": { + "bidder": { + "placementId": 625 + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "page": "https://display.eskimi-creatives.com/" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8], + "plcmt": 1 + }, + "ext": { + "bidder": { + "placementId": 625 + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "page": "https://display.eskimi-creatives.com/", + "ext": { + "placementId": 625 + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { + "id": "1", + "impid": "test-imp-id", + "price": 4.5, + "adm": "00:00:15", + "crid": "video-creative-1", + "w": 640, + "h": 480, + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "test-imp-id", + "price": 4.5, + "adm": "00:00:15", + "crid": "video-creative-1", + "w": 640, + "h": 480, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/app-ext-merge.json b/adapters/eskimi/eskimitest/supplemental/app-ext-merge.json new file mode 100644 index 0000000000..6c80e89ea3 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/app-ext-merge.json @@ -0,0 +1,71 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 320, "h": 50 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "app": { + "id": "app-1", + "bundle": "com.eskimi.example", + "ext": { + "installed": 1, + "data": { "category": "games" } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 320, "h": 50 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "app": { + "id": "app-1", + "bundle": "com.eskimi.example", + "ext": { + "installed": 1, + "data": { "category": "games" }, + "placementId": 625 + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "1", "impid": "test-imp-id", "price": 1.0, "crid": "c1", "w": 320, "h": 50, "mtype": 1 } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { "bid": { "id": "1", "impid": "test-imp-id", "price": 1.0, "crid": "c1", "w": 320, "h": 50, "mtype": 1 }, "type": "banner" } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/invalid-bidder-params.json b/adapters/eskimi/eskimitest/supplemental/invalid-bidder-params.json new file mode 100644 index 0000000000..8d491d5ec3 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/invalid-bidder-params.json @@ -0,0 +1,20 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "invalid imp.ext.bidder for imp test-imp-id:.*", + "comparison": "regex" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": "not-an-object" } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [] +} diff --git a/adapters/eskimi/eskimitest/supplemental/invalid-imp-ext.json b/adapters/eskimi/eskimitest/supplemental/invalid-imp-ext.json new file mode 100644 index 0000000000..126d58f573 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/invalid-imp-ext.json @@ -0,0 +1,20 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "invalid imp.ext for imp test-imp-id:.*", + "comparison": "regex" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": "not-an-object" + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [] +} diff --git a/adapters/eskimi/eskimitest/supplemental/invalid-response-body.json b/adapters/eskimi/eskimitest/supplemental/invalid-response-body.json new file mode 100644 index 0000000000..8b7a807ddd --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/invalid-response-body.json @@ -0,0 +1,50 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": "this-should-be-an-array" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": ".*", + "comparison": "regex" + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/multi-format-imp-battr-dual-write.json b/adapters/eskimi/eskimitest/supplemental/multi-format-imp-battr-dual-write.json new file mode 100644 index 0000000000..ab2959397a --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/multi-format-imp-battr-dual-write.json @@ -0,0 +1,86 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8] + }, + "ext": { + "bidder": { + "placementId": 625, + "battr": [13, 14] + } + } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { + "format": [{ "w": 300, "h": 250 }], + "battr": [13, 14] + }, + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8], + "battr": [13, 14] + }, + "ext": { + "bidder": { + "placementId": 625, + "battr": [13, 14] + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "1", "impid": "test-imp-id", "price": 2.5, "adm": "", "crid": "v-1", "w": 640, "h": 480, "mtype": 2 } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { "bid": { "id": "1", "impid": "test-imp-id", "price": 2.5, "adm": "", "crid": "v-1", "w": 640, "h": 480, "mtype": 2 }, "type": "video" } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/multi-format-imp-uses-mtype.json b/adapters/eskimi/eskimitest/supplemental/multi-format-imp-uses-mtype.json new file mode 100644 index 0000000000..81389b712c --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/multi-format-imp-uses-mtype.json @@ -0,0 +1,74 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8] + }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8] + }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "video-bid", "impid": "test-imp-id", "price": 4.0, "adm": "", "crid": "v-1", "w": 640, "h": 480, "mtype": 2 }, + { "id": "banner-bid", "impid": "test-imp-id", "price": 1.5, "adm": "
ad
", "crid": "b-1", "w": 300, "h": 250, "mtype": 1 } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { "bid": { "id": "video-bid", "impid": "test-imp-id", "price": 4.0, "adm": "", "crid": "v-1", "w": 640, "h": 480, "mtype": 2 }, "type": "video" }, + { "bid": { "id": "banner-bid", "impid": "test-imp-id", "price": 1.5, "adm": "
ad
", "crid": "b-1", "w": 300, "h": 250, "mtype": 1 }, "type": "banner" } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/multi-format-imp-without-mtype-errors.json b/adapters/eskimi/eskimitest/supplemental/multi-format-imp-without-mtype-errors.json new file mode 100644 index 0000000000..312f0f06b2 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/multi-format-imp-without-mtype-errors.json @@ -0,0 +1,76 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8] + }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8] + }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "ambiguous", "impid": "test-imp-id", "price": 2.0, "adm": "
?
", "crid": "c-1" } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "bid for multi-format imp test-imp-id requires bid.mtype to disambiguate", + "comparison": "literal" + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/multi-imp-asymmetry.json b/adapters/eskimi/eskimitest/supplemental/multi-imp-asymmetry.json new file mode 100644 index 0000000000..c712c0783e --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/multi-imp-asymmetry.json @@ -0,0 +1,103 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "imp-1", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { + "bidder": { + "placementId": 625, + "bcat": ["IAB-FROM-IMP-0"], + "bidFloor": 1.0 + } + } + }, + { + "id": "imp-2", + "banner": { "format": [{ "w": 728, "h": 90 }] }, + "ext": { + "bidder": { + "placementId": 999, + "bcat": ["IAB-FROM-IMP-1"], + "bidFloor": 2.0, + "bidFloorCur": "EUR" + } + } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "bcat": ["IAB-FROM-IMP-0"], + "imp": [ + { + "id": "imp-1", + "secure": 1, + "bidfloor": 1.0, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { + "bidder": { + "placementId": 625, + "bcat": ["IAB-FROM-IMP-0"], + "bidFloor": 1.0 + } + } + }, + { + "id": "imp-2", + "secure": 1, + "bidfloor": 2.0, + "bidfloorcur": "EUR", + "banner": { "format": [{ "w": 728, "h": 90 }] }, + "ext": { + "bidder": { + "placementId": 999, + "bcat": ["IAB-FROM-IMP-1"], + "bidFloor": 2.0, + "bidFloorCur": "EUR" + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["imp-1", "imp-2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "1", "impid": "imp-1", "price": 1.5, "crid": "c1", "w": 300, "h": 250 }, + { "id": "2", "impid": "imp-2", "price": 2.5, "crid": "c2", "w": 728, "h": 90 } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { "bid": { "id": "1", "impid": "imp-1", "price": 1.5, "crid": "c1", "w": 300, "h": 250 }, "type": "banner" }, + { "bid": { "id": "2", "impid": "imp-2", "price": 2.5, "crid": "c2", "w": 728, "h": 90 }, "type": "banner" } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/multi-imp-invalid-second-dropped.json b/adapters/eskimi/eskimitest/supplemental/multi-imp-invalid-second-dropped.json new file mode 100644 index 0000000000..da98bbb32d --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/multi-imp-invalid-second-dropped.json @@ -0,0 +1,79 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "invalid imp.ext.bidder for imp imp-2:.*", + "comparison": "regex" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "imp-1", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { + "bidder": { + "placementId": 625 + } + } + }, + { + "id": "imp-2", + "banner": { "format": [{ "w": 728, "h": 90 }] }, + "ext": { "bidder": "not-an-object" } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "imp-1", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { + "bidder": { + "placementId": 625 + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["imp-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "1", "impid": "imp-1", "price": 1.5, "crid": "c1", "w": 300, "h": 250, "mtype": 1 } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { "bid": { "id": "1", "impid": "imp-1", "price": 1.5, "crid": "c1", "w": 300, "h": 250, "mtype": 1 }, "type": "banner" } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/no-site-or-app.json b/adapters/eskimi/eskimitest/supplemental/no-site-or-app.json new file mode 100644 index 0000000000..6456b473b8 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/no-site-or-app.json @@ -0,0 +1,19 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "request must contain either site or app", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ] + }, + "httpCalls": [] +} diff --git a/adapters/eskimi/eskimitest/supplemental/pre-set-overrides-not-clobbered.json b/adapters/eskimi/eskimitest/supplemental/pre-set-overrides-not-clobbered.json new file mode 100644 index 0000000000..c0cddb72de --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/pre-set-overrides-not-clobbered.json @@ -0,0 +1,96 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "bcat": ["IAB-EXISTING"], + "badv": ["existing-blocked.com"], + "bapp": ["com.existing.blocked"], + "imp": [ + { + "id": "test-imp-id", + "bidfloor": 5.0, + "bidfloorcur": "USD", + "banner": { + "format": [{ "w": 300, "h": 250 }], + "battr": [3] + }, + "ext": { + "bidder": { + "placementId": 625, + "bcat": ["IAB-FROM-EXT"], + "badv": ["ext-blocked.com"], + "bapp": ["com.ext.blocked"], + "bidFloor": 1.0, + "bidFloorCur": "EUR", + "battr": [1, 2] + } + } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "bcat": ["IAB-EXISTING"], + "badv": ["existing-blocked.com"], + "bapp": ["com.existing.blocked"], + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "bidfloor": 5.0, + "bidfloorcur": "USD", + "banner": { + "format": [{ "w": 300, "h": 250 }], + "battr": [3] + }, + "ext": { + "bidder": { + "placementId": 625, + "bcat": ["IAB-FROM-EXT"], + "badv": ["ext-blocked.com"], + "bapp": ["com.ext.blocked"], + "bidFloor": 1.0, + "bidFloorCur": "EUR", + "battr": [1, 2] + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "1", "impid": "test-imp-id", "price": 6.0, "crid": "c1", "w": 300, "h": 250 } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { "bid": { "id": "1", "impid": "test-imp-id", "price": 6.0, "crid": "c1", "w": 300, "h": 250 }, "type": "banner" } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/privacy-signals-pass-through.json b/adapters/eskimi/eskimitest/supplemental/privacy-signals-pass-through.json new file mode 100644 index 0000000000..16f6f440bf --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/privacy-signals-pass-through.json @@ -0,0 +1,89 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" }, + "user": { + "ext": { + "consent": "CO12345abcdefghijklmnopqrstuvwxyz" + } + }, + "regs": { + "coppa": 1, + "us_privacy": "1YYY", + "gpp": "DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + "gpp_sid": [7, 8], + "ext": { + "gdpr": 1 + } + }, + "device": { + "lmt": 1, + "dnt": 1 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + }, + "user": { + "ext": { "consent": "CO12345abcdefghijklmnopqrstuvwxyz" } + }, + "regs": { + "coppa": 1, + "us_privacy": "1YYY", + "gpp": "DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + "gpp_sid": [7, 8], + "ext": { "gdpr": 1 } + }, + "device": { "lmt": 1, "dnt": 1 } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "1", "impid": "test-imp-id", "price": 1.0, "crid": "c1", "w": 300, "h": 250 } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { "bid": { "id": "1", "impid": "test-imp-id", "price": 1.0, "crid": "c1", "w": 300, "h": 250 }, "type": "banner" } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/response-204.json b/adapters/eskimi/eskimitest/supplemental/response-204.json new file mode 100644 index 0000000000..b82f4f1ff8 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/response-204.json @@ -0,0 +1,41 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/eskimi/eskimitest/supplemental/response-400.json b/adapters/eskimi/eskimitest/supplemental/response-400.json new file mode 100644 index 0000000000..81d636608c --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/response-400.json @@ -0,0 +1,46 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "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/eskimi/eskimitest/supplemental/response-500.json b/adapters/eskimi/eskimitest/supplemental/response-500.json new file mode 100644 index 0000000000..daf7265354 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/response-500.json @@ -0,0 +1,46 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "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/eskimi/eskimitest/supplemental/response-no-cur.json b/adapters/eskimi/eskimitest/supplemental/response-no-cur.json new file mode 100644 index 0000000000..43a8eae814 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/response-no-cur.json @@ -0,0 +1,59 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "1", "impid": "test-imp-id", "price": 1.0, "crid": "c1", "w": 300, "h": 250 } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { "bid": { "id": "1", "impid": "test-imp-id", "price": 1.0, "crid": "c1", "w": 300, "h": 250 }, "type": "banner" } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/schain-pass-through.json b/adapters/eskimi/eskimitest/supplemental/schain-pass-through.json new file mode 100644 index 0000000000..fc3b0d5841 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/schain-pass-through.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" }, + "source": { + "schain": { + "complete": 1, + "ver": "1.0", + "nodes": [ + { "asi": "publisher.com", "sid": "pub-sid-1", "hp": 1 }, + { "asi": "ssp.example", "sid": "ssp-sid-2", "hp": 1 } + ] + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + }, + "source": { + "schain": { + "complete": 1, + "ver": "1.0", + "nodes": [ + { "asi": "publisher.com", "sid": "pub-sid-1", "hp": 1 }, + { "asi": "ssp.example", "sid": "ssp-sid-2", "hp": 1 } + ] + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "1", "impid": "test-imp-id", "price": 1.0, "crid": "c1", "w": 300, "h": 250 } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { "bid": { "id": "1", "impid": "test-imp-id", "price": 1.0, "crid": "c1", "w": 300, "h": 250 }, "type": "banner" } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/site-ext-merge.json b/adapters/eskimi/eskimitest/supplemental/site-ext-merge.json new file mode 100644 index 0000000000..a6cfa15fe3 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/site-ext-merge.json @@ -0,0 +1,71 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { + "amp": 0, + "data": { "category": "news" } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { + "amp": 0, + "data": { "category": "news" }, + "placementId": 625 + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "1", "impid": "test-imp-id", "price": 1.0, "crid": "c1", "w": 300, "h": 250 } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { "bid": { "id": "1", "impid": "test-imp-id", "price": 1.0, "crid": "c1", "w": 300, "h": 250 }, "type": "banner" } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/unmatched-bid-impid.json b/adapters/eskimi/eskimitest/supplemental/unmatched-bid-impid.json new file mode 100644 index 0000000000..0675afde99 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/unmatched-bid-impid.json @@ -0,0 +1,64 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "b1", "impid": "unknown-imp", "price": 1.0, "crid": "c1" } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unable to resolve media type for impression unknown-imp", + "comparison": "literal" + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/unsupported-bid-media-type.json b/adapters/eskimi/eskimitest/supplemental/unsupported-bid-media-type.json new file mode 100644 index 0000000000..4fd0906dfd --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/unsupported-bid-media-type.json @@ -0,0 +1,75 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + }, + { + "id": "native-imp", + "native": { "request": "{}" }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "ext": { "bidder": { "placementId": 625 } } + }, + { + "id": "native-imp", + "secure": 1, + "native": { "request": "{}" }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["test-imp-id", "native-imp"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "1", "impid": "native-imp", "price": 1.0, "crid": "c1" } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unsupported media type for impression native-imp (banner and video only)", + "comparison": "literal" + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/video-no-mtype-inferred.json b/adapters/eskimi/eskimitest/supplemental/video-no-mtype-inferred.json new file mode 100644 index 0000000000..28200c899c --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/video-no-mtype-inferred.json @@ -0,0 +1,70 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8] + }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "protocols": [2, 3, 5, 6, 7, 8] + }, + "ext": { "bidder": { "placementId": 625 } } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { "id": "1", "impid": "test-imp-id", "price": 3.0, "adm": "", "crid": "v-1", "w": 640, "h": 480 } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { "bid": { "id": "1", "impid": "test-imp-id", "price": 3.0, "adm": "", "crid": "v-1", "w": 640, "h": 480 }, "type": "video" } + ] + } + ] +} diff --git a/adapters/eskimi/eskimitest/supplemental/video-outstream-web.json b/adapters/eskimi/eskimitest/supplemental/video-outstream-web.json new file mode 100644 index 0000000000..0d6ab19885 --- /dev/null +++ b/adapters/eskimi/eskimitest/supplemental/video-outstream-web.json @@ -0,0 +1,104 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360, + "protocols": [2, 3, 5, 6, 7, 8], + "plcmt": 4 + }, + "ext": { + "bidder": { + "placementId": 625, + "battr": [13, 14] + } + } + } + ], + "site": { "id": "271", "domain": "display.eskimi-creatives.com" } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ittr.eskimi.com/prebidjs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "secure": 1, + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360, + "protocols": [2, 3, 5, 6, 7, 8], + "plcmt": 4, + "battr": [13, 14] + }, + "ext": { + "bidder": { + "placementId": 625, + "battr": [13, 14] + } + } + } + ], + "site": { + "id": "271", + "domain": "display.eskimi-creatives.com", + "ext": { "placementId": 625 } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "eskimi", + "bid": [ + { + "id": "1", + "impid": "test-imp-id", + "price": 3.5, + "adm": "", + "crid": "outstream-1", + "w": 640, + "h": 360, + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "test-imp-id", + "price": 3.5, + "adm": "", + "crid": "outstream-1", + "w": 640, + "h": 360, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/eskimi/params_test.go b/adapters/eskimi/params_test.go new file mode 100644 index 0000000000..a2c559e90e --- /dev/null +++ b/adapters/eskimi/params_test.go @@ -0,0 +1,56 @@ +package eskimi + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/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.BidderEskimi, 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.BidderEskimi, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"placementId":625}`, + `{"placementId":625,"bidFloor":0.5,"bidFloorCur":"USD"}`, + `{"placementId":625,"bcat":["IAB1"],"badv":["bad.com"],"bapp":["com.bad.app"]}`, + `{"placementId":625,"battr":[1,2,17]}`, +} + +var invalidParams = []string{ + ``, + `null`, + `{}`, + `{"placementId":"625"}`, + `{"placementId":625.5}`, + `{"placementId":0}`, + `{"placementId":-1}`, + `{"bidFloor":0.5}`, + `{"placementId":625,"bcat":"IAB1"}`, + `{"placementId":625,"battr":[0]}`, + `{"placementId":625,"battr":[18]}`, + `{"placementId":625,"unknownField":"foo"}`, +} diff --git a/adapters/exco/exco.go b/adapters/exco/exco.go index dc79c6ec1e..49f519691f 100644 --- a/adapters/exco/exco.go +++ b/adapters/exco/exco.go @@ -5,11 +5,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/exco/exco_test.go b/adapters/exco/exco_test.go index 77ab4afe88..faa955569e 100644 --- a/adapters/exco/exco_test.go +++ b/adapters/exco/exco_test.go @@ -3,9 +3,9 @@ package exco 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/exco/params_test.go b/adapters/exco/params_test.go index eed4bc4b64..73fc0d657a 100644 --- a/adapters/exco/params_test.go +++ b/adapters/exco/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/exco.json diff --git a/adapters/ezoic/ezoic.go b/adapters/ezoic/ezoic.go new file mode 100644 index 0000000000..fd5e51950d --- /dev/null +++ b/adapters/ezoic/ezoic.go @@ -0,0 +1,95 @@ +package ezoic + +import ( + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Ezoic adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, cfg config.Adapter, server config.Server) (adapters.Bidder, error) { + return &adapter{endpoint: cfg.Endpoint}, nil +} + +// MakeRequests forwards the OpenRTB request to the Ezoic bidder endpoint +// unchanged. Eligibility, demand selection, and creative construction all +// happen server-side at Ezoic; the adapter is a deliberately thin transport. +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + body, err := jsonutil.Marshal(request) + if err != nil { + return nil, []error{fmt.Errorf("unable to marshal openrtb request: %w", err)} + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + return []*adapters.RequestData{{ + Method: http.MethodPost, + Uri: a.endpoint, + Body: body, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }}, nil +} + +// MakeBids unpacks the Ezoic endpoint's OpenRTB BidResponse. +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 bidResp openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &bidResp); err != nil { + return nil, []error{err} + } + + bidderResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if bidResp.Cur != "" { + bidderResponse.Currency = bidResp.Cur + } + + var errs []error + for _, seatBid := range bidResp.SeatBid { + for i := range seatBid.Bid { + bidType, err := getMediaTypeForBid(seatBid.Bid[i]) + if err != nil { + errs = append(errs, err) + continue + } + bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + }) + } + } + return bidderResponse, errs +} + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.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), + } + } +} diff --git a/adapters/ezoic/ezoic_test.go b/adapters/ezoic/ezoic_test.go new file mode 100644 index 0000000000..0c9a24a953 --- /dev/null +++ b/adapters/ezoic/ezoic_test.go @@ -0,0 +1,57 @@ +package ezoic + +import ( + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +const testsBidderEndpoint = "https://g.ezoic.net/ezoic/prebid/adapter/ortb" + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderEzoic, config.Adapter{ + Endpoint: testsBidderEndpoint}, config.Server{}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "ezoictest", bidder) +} + +func TestNoContentResponse(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderEzoic, config.Adapter{ + Endpoint: testsBidderEndpoint}, config.Server{}) + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + bidResponse, errs := bidder.MakeBids(nil, nil, &adapters.ResponseData{StatusCode: 204}) + assert.Nil(t, bidResponse) + assert.Empty(t, errs) +} + +func TestGetMediaTypeForBid(t *testing.T) { + bidType, err := getMediaTypeForBid(openrtb2.Bid{MType: openrtb2.MarkupBanner}) + assert.NoError(t, err) + assert.Equal(t, openrtb_ext.BidTypeBanner, bidType) + + bidType, err = getMediaTypeForBid(openrtb2.Bid{MType: openrtb2.MarkupVideo}) + assert.NoError(t, err) + assert.Equal(t, openrtb_ext.BidTypeVideo, bidType) + + bidType, err = getMediaTypeForBid(openrtb2.Bid{MType: openrtb2.MarkupNative}) + assert.NoError(t, err) + assert.Equal(t, openrtb_ext.BidTypeNative, bidType) + + _, err = getMediaTypeForBid(openrtb2.Bid{ID: "no-mtype"}) + assert.Error(t, err) + + _, err = getMediaTypeForBid(openrtb2.Bid{ID: "audio", MType: openrtb2.MarkupAudio}) + assert.Error(t, err) +} diff --git a/adapters/ezoic/ezoictest/exemplary/simple-banner.json b/adapters/ezoic/ezoictest/exemplary/simple-banner.json new file mode 100644 index 0000000000..7c3c29b291 --- /dev/null +++ b/adapters/ezoic/ezoictest/exemplary/simple-banner.json @@ -0,0 +1,124 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "tmax": 750, + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "device": { + "ua": "test-user-agent", + "ip": "203.0.113.9" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "div-gpt-ad-1", + "bidfloor": 0.25, + "bidfloorcur": "USD", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "ezoic-placement-1" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://g.ezoic.net/ezoic/prebid/adapter/ortb", + "body": { + "id": "test-request-id", + "tmax": 750, + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "device": { + "ua": "test-user-agent", + "ip": "203.0.113.9" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "div-gpt-ad-1", + "bidfloor": 0.25, + "bidfloorcur": "USD", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "ezoic-placement-1" + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "ezoic", + "bid": [ + { + "id": "ezoic-bid-1", + "impid": "test-imp-id", + "price": 2.5, + "adm": "
ezoic-self-tracking-creative
", + "crid": "ezoic-creative-1", + "w": 300, + "h": 250, + "mtype": 1, + "exp": 300 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "ezoic-bid-1", + "impid": "test-imp-id", + "price": 2.5, + "adm": "
ezoic-self-tracking-creative
", + "crid": "ezoic-creative-1", + "w": 300, + "h": 250, + "mtype": 1, + "exp": 300 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/ezoic/ezoictest/exemplary/simple-native.json b/adapters/ezoic/ezoictest/exemplary/simple-native.json new file mode 100644 index 0000000000..31a072cd61 --- /dev/null +++ b/adapters/ezoic/ezoictest/exemplary/simple-native.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "tmax": 750, + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "device": { + "ua": "test-user-agent", + "ip": "203.0.113.9" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "div-gpt-ad-1", + "bidfloor": 0.25, + "bidfloorcur": "USD", + "native": { + "ver": "1.2", + "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":90}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"w\":1200,\"h\":627}}]}" + }, + "ext": { + "bidder": { + "placementId": "ezoic-placement-1" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://g.ezoic.net/ezoic/prebid/adapter/ortb", + "body": { + "id": "test-request-id", + "tmax": 750, + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "device": { + "ua": "test-user-agent", + "ip": "203.0.113.9" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "div-gpt-ad-1", + "bidfloor": 0.25, + "bidfloorcur": "USD", + "native": { + "ver": "1.2", + "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":90}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"w\":1200,\"h\":627}}]}" + }, + "ext": { + "bidder": { + "placementId": "ezoic-placement-1" + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "ezoic", + "bid": [ + { + "id": "ezoic-bid-1", + "impid": "test-imp-id", + "price": 1.75, + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"ezoic native title\"}}],\"link\":{\"url\":\"https://example.com/click\"}}}", + "crid": "ezoic-creative-1", + "mtype": 4, + "exp": 300 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "ezoic-bid-1", + "impid": "test-imp-id", + "price": 1.75, + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"ezoic native title\"}}],\"link\":{\"url\":\"https://example.com/click\"}}}", + "crid": "ezoic-creative-1", + "mtype": 4, + "exp": 300 + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/ezoic/ezoictest/exemplary/simple-video.json b/adapters/ezoic/ezoictest/exemplary/simple-video.json new file mode 100644 index 0000000000..6db45edc5e --- /dev/null +++ b/adapters/ezoic/ezoictest/exemplary/simple-video.json @@ -0,0 +1,138 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "tmax": 750, + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "device": { + "ua": "test-user-agent", + "ip": "203.0.113.9" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "div-gpt-ad-1", + "bidfloor": 0.25, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 640, + "h": 480, + "minduration": 5, + "maxduration": 30 + }, + "ext": { + "bidder": { + "placementId": "ezoic-placement-1" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://g.ezoic.net/ezoic/prebid/adapter/ortb", + "body": { + "id": "test-request-id", + "tmax": 750, + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "device": { + "ua": "test-user-agent", + "ip": "203.0.113.9" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "div-gpt-ad-1", + "bidfloor": 0.25, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 640, + "h": 480, + "minduration": 5, + "maxduration": 30 + }, + "ext": { + "bidder": { + "placementId": "ezoic-placement-1" + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "ezoic", + "bid": [ + { + "id": "ezoic-bid-1", + "impid": "test-imp-id", + "price": 4.5, + "adm": "", + "crid": "ezoic-creative-1", + "w": 640, + "h": 480, + "mtype": 2, + "exp": 300 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "ezoic-bid-1", + "impid": "test-imp-id", + "price": 4.5, + "adm": "", + "crid": "ezoic-creative-1", + "w": 640, + "h": 480, + "mtype": 2, + "exp": 300 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/ezoic/ezoictest/supplemental/invalid-response.json b/adapters/ezoic/ezoictest/supplemental/invalid-response.json new file mode 100644 index 0000000000..adcb3c1001 --- /dev/null +++ b/adapters/ezoic/ezoictest/supplemental/invalid-response.json @@ -0,0 +1,69 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://g.ezoic.net/ezoic/prebid/adapter/ortb", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": "invalid response" + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "expect", + "comparison": "regex" + } + ] +} diff --git a/adapters/adsinteractive/adsinteractivetest/supplemental/no-content-204.json b/adapters/ezoic/ezoictest/supplemental/status-204.json similarity index 63% rename from adapters/adsinteractive/adsinteractivetest/supplemental/no-content-204.json rename to adapters/ezoic/ezoictest/supplemental/status-204.json index ee5adb9193..2c60ef485a 100644 --- a/adapters/adsinteractive/adsinteractivetest/supplemental/no-content-204.json +++ b/adapters/ezoic/ezoictest/supplemental/status-204.json @@ -1,9 +1,13 @@ { "mockBidRequest": { "id": "test-request-id", + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, "imp": [ { - "id": "fake-imp-id", + "id": "test-imp-id", "banner": { "format": [ { @@ -13,22 +17,24 @@ ] }, "ext": { - "bidder": { - } + "bidder": {} } } ] }, - "httpCalls": [ { "expectedRequest": { - "uri": "http://bid.adsinteractive.com/prebid", + "uri": "https://g.ezoic.net/ezoic/prebid/adapter/ortb", "body": { "id": "test-request-id", + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, "imp": [ { - "id": "fake-imp-id", + "id": "test-imp-id", "banner": { "format": [ { @@ -38,13 +44,14 @@ ] }, "ext": { - "bidder": { - } + "bidder": {} } } ] }, - "impIDs":["fake-imp-id"] + "impIDs": [ + "test-imp-id" + ] }, "mockResponse": { "status": 204, @@ -52,6 +59,5 @@ } } ], - "expectedBidResponses": [] } diff --git a/adapters/ezoic/ezoictest/supplemental/status-400.json b/adapters/ezoic/ezoictest/supplemental/status-400.json new file mode 100644 index 0000000000..8d156eb86a --- /dev/null +++ b/adapters/ezoic/ezoictest/supplemental/status-400.json @@ -0,0 +1,69 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://g.ezoic.net/ezoic/prebid/adapter/ortb", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/ezoic/ezoictest/supplemental/status-500.json b/adapters/ezoic/ezoictest/supplemental/status-500.json new file mode 100644 index 0000000000..1d0b418290 --- /dev/null +++ b/adapters/ezoic/ezoictest/supplemental/status-500.json @@ -0,0 +1,69 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://g.ezoic.net/ezoic/prebid/adapter/ortb", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 500, + "body": {} + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/ezoic/ezoictest/supplemental/unsupported-mtype.json b/adapters/ezoic/ezoictest/supplemental/unsupported-mtype.json new file mode 100644 index 0000000000..39d7506d66 --- /dev/null +++ b/adapters/ezoic/ezoictest/supplemental/unsupported-mtype.json @@ -0,0 +1,117 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://g.ezoic.net/ezoic/prebid/adapter/ortb", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com/article", + "domain": "example.com" + }, + "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", + "cur": "USD", + "seatbid": [ + { + "seat": "ezoic", + "bid": [ + { + "id": "ezoic-bid-good", + "impid": "test-imp-id", + "price": 1.25, + "adm": "
creative
", + "crid": "ezoic-creative-1", + "w": 300, + "h": 250, + "mtype": 1 + }, + { + "id": "ezoic-bid-no-mtype", + "impid": "test-imp-id", + "price": 9.99, + "adm": "
creative
", + "crid": "ezoic-creative-2", + "w": 300, + "h": 250 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "ezoic-bid-good", + "impid": "test-imp-id", + "price": 1.25, + "adm": "
creative
", + "crid": "ezoic-creative-1", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unsupported mtype 0 for bid ezoic-bid-no-mtype", + "comparison": "literal" + } + ] +} diff --git a/adapters/ezoic/params_test.go b/adapters/ezoic/params_test.go new file mode 100644 index 0000000000..91994fe4cf --- /dev/null +++ b/adapters/ezoic/params_test.go @@ -0,0 +1,52 @@ +package ezoic + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/openrtb_ext" +) + +// This file intends to test static/bidder-params/ezoic.json +// +// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.ezoic + +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.BidderEzoic, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected ezoic 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.BidderEzoic, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{}`, + `{"placementId": "ezoic-placement-1"}`, +} + +var invalidParams = []string{ + `null`, + `true`, + `[]`, + `"placementId"`, + `{"placementId": 12345}`, + `{"placementId": true}`, +} diff --git a/adapters/feedad/feedad.go b/adapters/feedad/feedad.go index 804027ee11..6a1c1314db 100644 --- a/adapters/feedad/feedad.go +++ b/adapters/feedad/feedad.go @@ -4,10 +4,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const feedAdAdapterVersion = "1.0.0" diff --git a/adapters/feedad/feedad_test.go b/adapters/feedad/feedad_test.go index 28993850df..66e7414f56 100644 --- a/adapters/feedad/feedad_test.go +++ b/adapters/feedad/feedad_test.go @@ -3,9 +3,9 @@ package feedad 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/feedad/params_test.go b/adapters/feedad/params_test.go index a77ad9ae46..279b6c6c6d 100644 --- a/adapters/feedad/params_test.go +++ b/adapters/feedad/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/flatads/flatads.go b/adapters/flatads/flatads.go index 0bf0b979e7..5bd1532ab7 100644 --- a/adapters/flatads/flatads.go +++ b/adapters/flatads/flatads.go @@ -6,12 +6,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/flatads/flatads_test.go b/adapters/flatads/flatads_test.go index b3b3cf33f7..6bd5187f01 100644 --- a/adapters/flatads/flatads_test.go +++ b/adapters/flatads/flatads_test.go @@ -3,9 +3,9 @@ package flatads 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/flatads/params_test.go b/adapters/flatads/params_test.go index c58546399b..98c583695e 100644 --- a/adapters/flatads/params_test.go +++ b/adapters/flatads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/flipp/flipp.go b/adapters/flipp/flipp.go index 4ac5c31c76..fa8259b80a 100644 --- a/adapters/flipp/flipp.go +++ b/adapters/flipp/flipp.go @@ -13,11 +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/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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/uuidutil" ) const ( diff --git a/adapters/flipp/flipp_params.go b/adapters/flipp/flipp_params.go index 34d266a7d9..3e86337916 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/v3/openrtb_ext" +import "github.com/prebid/prebid-server/v4/openrtb_ext" type CampaignRequestBodyUser struct { Key *string `json:"key"` diff --git a/adapters/flipp/flipp_test.go b/adapters/flipp/flipp_test.go index 8215dabe82..3676053f04 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/flipp/params_test.go b/adapters/flipp/params_test.go index 24f30b0a62..01d4604c0a 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/freewheelssp/freewheelssp.go b/adapters/freewheelssp/freewheelssp.go index 111b05a60e..6e4ad67228 100644 --- a/adapters/freewheelssp/freewheelssp.go +++ b/adapters/freewheelssp/freewheelssp.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/freewheelssp/freewheelssp_test.go b/adapters/freewheelssp/freewheelssp_test.go index ba5e6cf9aa..d8d3350907 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/frvradn/frvradn.go b/adapters/frvradn/frvradn.go index 5b21263b1a..4b307c7626 100644 --- a/adapters/frvradn/frvradn.go +++ b/adapters/frvradn/frvradn.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/frvradn/frvradn_test.go b/adapters/frvradn/frvradn_test.go index 514ef6c712..e69c10d865 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/frvradn/params_test.go b/adapters/frvradn/params_test.go index 83e1ba631a..3d054db074 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/fwssp/fwssp.go b/adapters/fwssp/fwssp.go index 3ee896e156..ae916dc511 100644 --- a/adapters/fwssp/fwssp.go +++ b/adapters/fwssp/fwssp.go @@ -5,11 +5,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/fwssp/fwssp_test.go b/adapters/fwssp/fwssp_test.go index 7afd5197fd..5d9d6a8801 100644 --- a/adapters/fwssp/fwssp_test.go +++ b/adapters/fwssp/fwssp_test.go @@ -3,9 +3,9 @@ package fwssp 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/fwssp/params_test.go b/adapters/fwssp/params_test.go index 366078c016..a413b51d35 100644 --- a/adapters/fwssp/params_test.go +++ b/adapters/fwssp/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/gamma/gamma.go b/adapters/gamma/gamma.go index 66f99953fe..57edc810e8 100644 --- a/adapters/gamma/gamma.go +++ b/adapters/gamma/gamma.go @@ -9,11 +9,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/openrtb/v20/openrtb3" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type GammaAdapter struct { diff --git a/adapters/gamma/gamma_test.go b/adapters/gamma/gamma_test.go index 9556e83dc0..0c50d48662 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/gamma/params_test.go b/adapters/gamma/params_test.go index d377b50c3d..06f6d6faba 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 4ba302506f..b4cd7841e5 100644 --- a/adapters/gamoshi/gamoshi.go +++ b/adapters/gamoshi/gamoshi.go @@ -7,11 +7,11 @@ import ( "strconv" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type GamoshiAdapter struct { diff --git a/adapters/gamoshi/gamoshi_test.go b/adapters/gamoshi/gamoshi_test.go index aa20723b2d..ee572b2aca 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamplesWithConfiguredURI(t *testing.T) { diff --git a/adapters/gamoshi/params_test.go b/adapters/gamoshi/params_test.go index 429ed96ad8..21f887d686 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 a2b2dc5b9a..cbdc899e80 100644 --- a/adapters/globalsun/globalsun.go +++ b/adapters/globalsun/globalsun.go @@ -7,11 +7,11 @@ import ( "github.com/buger/jsonparser" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/globalsun/globalsun_test.go b/adapters/globalsun/globalsun_test.go index e34805f68f..cfbebe3135 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/globalsun/params_test.go b/adapters/globalsun/params_test.go index b4fe0ede7a..9847ce3d29 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/goldbach/goldbach.go b/adapters/goldbach/goldbach.go index 5c500e63ce..3d47a4b3dd 100644 --- a/adapters/goldbach/goldbach.go +++ b/adapters/goldbach/goldbach.go @@ -5,11 +5,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/goldbach/goldbach_test.go b/adapters/goldbach/goldbach_test.go index a1f046adfe..55c5ea75fe 100644 --- a/adapters/goldbach/goldbach_test.go +++ b/adapters/goldbach/goldbach_test.go @@ -3,9 +3,9 @@ package goldbach 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/require" ) diff --git a/adapters/goldbach/params_test.go b/adapters/goldbach/params_test.go index b03d182247..0ef079fa80 100644 --- a/adapters/goldbach/params_test.go +++ b/adapters/goldbach/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/require" ) diff --git a/adapters/gothamads/gothamads_test.go b/adapters/gothamads/gothamads_test.go deleted file mode 100644 index b3433ae44a..0000000000 --- a/adapters/gothamads/gothamads_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package gothamads - -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.BidderGothamads, config.Adapter{ - Endpoint: "http://us-e-node1.gothamads.com/?pass={{.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, "gothamadstest", bidder) -} - -func TestEndpointTemplateMalformed(t *testing.T) { - _, buildErr := Builder(openrtb_ext.BidderGothamads, config.Adapter{ - Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - assert.Error(t, buildErr) -} diff --git a/adapters/grid/grid.go b/adapters/grid/grid.go index ad61058fed..b0b4304f73 100644 --- a/adapters/grid/grid.go +++ b/adapters/grid/grid.go @@ -9,12 +9,12 @@ import ( "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" - "github.com/prebid/prebid-server/v3/util/maputil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/maputil" ) type GridAdapter struct { diff --git a/adapters/grid/grid_test.go b/adapters/grid/grid_test.go index bf7bfe547f..652ae514cc 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/gumgum/gumgum.go b/adapters/gumgum/gumgum.go index 943ccfdf14..08681a48a5 100644 --- a/adapters/gumgum/gumgum.go +++ b/adapters/gumgum/gumgum.go @@ -8,11 +8,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // adapter implements Bidder interface. diff --git a/adapters/gumgum/gumgum_test.go b/adapters/gumgum/gumgum_test.go index 6386818803..852f672678 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/gumgum/params_test.go b/adapters/gumgum/params_test.go index 514ab1d8c7..a67c7695e4 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/huaweiads/huaweiads.go b/adapters/huaweiads/huaweiads.go index 144f5e2220..6466e2b9b7 100644 --- a/adapters/huaweiads/huaweiads.go +++ b/adapters/huaweiads/huaweiads.go @@ -20,12 +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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) const huaweiAdxApiVersion = "3.4" diff --git a/adapters/huaweiads/huaweiads_test.go b/adapters/huaweiads/huaweiads_test.go index c6fd17feaa..aa6e788afa 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/huaweiads/params_test.go b/adapters/huaweiads/params_test.go index 9c4b5b36d2..22c1d1e527 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/imds/imds.go b/adapters/imds/imds.go index a5f53d6036..18a7284612 100644 --- a/adapters/imds/imds.go +++ b/adapters/imds/imds.go @@ -8,12 +8,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const adapterVersion string = "pbs-go/1.0.0" diff --git a/adapters/imds/imds_test.go b/adapters/imds/imds_test.go index 40a00462c1..525b2e6de5 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/imds/params_test.go b/adapters/imds/params_test.go index d98fe04cd1..2aa4a6b5e4 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 52f20ddd8d..eca008f150 100644 --- a/adapters/impactify/impactify.go +++ b/adapters/impactify/impactify.go @@ -8,11 +8,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/impactify/impactify_test.go b/adapters/impactify/impactify_test.go index 2385c5c64a..31be74f2fa 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/impactify/params_test.go b/adapters/impactify/params_test.go index 589e090172..d8b4626092 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/improvedigital/improvedigital.go b/adapters/improvedigital/improvedigital.go index 13534cc6dd..3821087d14 100644 --- a/adapters/improvedigital/improvedigital.go +++ b/adapters/improvedigital/improvedigital.go @@ -9,11 +9,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/adapters/improvedigital/improvedigital_test.go b/adapters/improvedigital/improvedigital_test.go index cd00aeaab7..ecb0007f9c 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/improvedigital/params_test.go b/adapters/improvedigital/params_test.go index abb1491fb0..4b3c9cea9a 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/infoawarebidder.go b/adapters/infoawarebidder.go index 6ccc039b48..414a9d3599 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/v3/config" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/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 5a28e506cc..1008cadcbe 100644 --- a/adapters/infoawarebidder_test.go +++ b/adapters/infoawarebidder_test.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "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/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/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 1d0c70123a..1d2a7b29d8 100644 --- a/adapters/infytv/infytv.go +++ b/adapters/infytv/infytv.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/infytv/infytv_test.go b/adapters/infytv/infytv_test.go index 85a4dd4b9b..c9d8c140cb 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/infytv/params_test.go b/adapters/infytv/params_test.go index 671a5a4e71..7ab22349be 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/inmobi/inmobi.go b/adapters/inmobi/inmobi.go index f79151bea8..6aa6422127 100644 --- a/adapters/inmobi/inmobi.go +++ b/adapters/inmobi/inmobi.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type InMobiAdapter struct { diff --git a/adapters/inmobi/inmobi_test.go b/adapters/inmobi/inmobi_test.go index 89884a8dde..67f095f86a 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index fc8487971b..2d0014c2c5 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -3,15 +3,16 @@ package insticator import ( "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" - "github.com/prebid/prebid-server/v3/util/mathutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/mathutil" ) type ext struct { @@ -24,7 +25,12 @@ type impInsticatorExt struct { } type adapter struct { - endpoint string + endpoint string + extraInfo ExtraInfo +} + +type ExtraInfo struct { + AppEndpoint string `json:"app_endpoint,omitempty"` } type reqExt struct { @@ -54,12 +60,53 @@ type bidInsticatorExt struct { // Builder builds a new instance of the Insticator adapter with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + extraInfo, err := parseExtraInfo(config.ExtraAdapterInfo) + if err != nil { + return nil, err + } + bidder := &adapter{ - endpoint: config.Endpoint, + endpoint: config.Endpoint, + extraInfo: extraInfo, } return bidder, nil } +func parseExtraInfo(v string) (ExtraInfo, error) { + if len(v) == 0 { + return ExtraInfo{}, nil + } + + var extraInfo ExtraInfo + if err := jsonutil.Unmarshal([]byte(v), &extraInfo); err != nil { + return extraInfo, fmt.Errorf("invalid extra info: %v", err) + } + + return extraInfo, nil +} + +// buildEndpointURL builds the endpoint URL with publisherId query parameter +func (a *adapter) buildEndpointURL(publisherId string, request *openrtb2.BidRequest) string { + // Use app endpoint from extra_info if this is an app request + baseEndpoint := a.endpoint + if request.App != nil && a.extraInfo.AppEndpoint != "" { + baseEndpoint = a.extraInfo.AppEndpoint + } + + // Append publisherId as query parameter + if publisherId != "" { + parsedURL, err := url.Parse(baseEndpoint) + if err == nil { + query := parsedURL.Query() + query.Set("publisherId", publisherId) + parsedURL.RawQuery = query.Encode() + return parsedURL.String() + } + } + + return baseEndpoint +} + // getMediaTypeForBid figures out which media type this bid is for func getMediaTypeForBid(bid *openrtb2.Bid) openrtb_ext.BidType { switch bid.MType { @@ -76,6 +123,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte var errs []error var adapterRequests []*adapters.RequestData var groupedImps = make(map[string][]openrtb2.Imp) + var publisherId string reqExt, err := makeReqExt(request) if err != nil { @@ -89,14 +137,15 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte isPublisherIdPopulated := false // Flag to track if populatePublisherId has been called for i := 0; i < len(request.Imp); i++ { - impCopy, impKey, publisherId, err := makeImps(request.Imp[i]) + impCopy, impKey, impPublisherId, err := makeImps(request.Imp[i]) if err != nil { errs = append(errs, err) continue } - // Populate publisher.id from imp extension + // Populate publisher.id from imp extension (only once) if !isPublisherIdPopulated { + publisherId = impPublisherId populatePublisherId(publisherId, &requestCopy) isPublisherIdPopulated = true } @@ -118,7 +167,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } for _, impList := range groupedImps { - if adapterReq, err := a.makeRequest(&requestCopy, impList); err == nil { + if adapterReq, err := a.makeRequest(&requestCopy, impList, publisherId); err == nil { adapterRequests = append(adapterRequests, adapterReq) } else { errs = append(errs, err) @@ -127,7 +176,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte return adapterRequests, errs } -func (a *adapter) makeRequest(request *openrtb2.BidRequest, impList []openrtb2.Imp) (*adapters.RequestData, error) { +func (a *adapter) makeRequest(request *openrtb2.BidRequest, impList []openrtb2.Imp, publisherId string) (*adapters.RequestData, error) { request.Imp = impList reqJSON, err := jsonutil.Marshal(request) @@ -135,6 +184,9 @@ func (a *adapter) makeRequest(request *openrtb2.BidRequest, impList []openrtb2.I return nil, err } + // Build endpoint URL with publisherId query parameter + endpointURL := a.buildEndpointURL(publisherId, request) + headers := http.Header{} headers.Add("Content-Type", "application/json;charset=utf-8") headers.Add("Accept", "application/json") @@ -156,7 +208,7 @@ func (a *adapter) makeRequest(request *openrtb2.BidRequest, impList []openrtb2.I return &adapters.RequestData{ Method: "POST", - Uri: a.endpoint, + Uri: endpointURL, Body: reqJSON, Headers: headers, ImpIDs: openrtb_ext.GetImpIDs(request.Imp), @@ -186,8 +238,10 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R bid := &seatBid.Bid[i] bidType := getMediaTypeForBid(bid) b := &adapters.TypedBid{ - Bid: &seatBid.Bid[i], - BidType: bidType, + Bid: &seatBid.Bid[i], + BidType: bidType, + BidMeta: getBidMeta(bid, bidType, seatBid.Seat), + BidVideo: getBidVideo(bid, bidType), } bidResponse.Bids = append(bidResponse.Bids, b) } @@ -195,6 +249,42 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R return bidResponse, nil } +// getBidMeta extracts metadata from the bid for brand safety and reporting +func getBidMeta(bid *openrtb2.Bid, bidType openrtb_ext.BidType, seat string) *openrtb_ext.ExtBidPrebidMeta { + meta := &openrtb_ext.ExtBidPrebidMeta{ + MediaType: string(bidType), + Seat: seat, + } + + if len(bid.ADomain) > 0 { + meta.AdvertiserDomains = bid.ADomain + } + + if len(bid.Cat) > 0 { + meta.PrimaryCategoryID = bid.Cat[0] + meta.SecondaryCategoryIDs = bid.Cat[1:] + } + + return meta +} + +// getBidVideo extracts video-specific metadata from the bid +func getBidVideo(bid *openrtb2.Bid, bidType openrtb_ext.BidType) *openrtb_ext.ExtBidPrebidVideo { + if bidType != openrtb_ext.BidTypeVideo { + return nil + } + + var primaryCategory string + if len(bid.Cat) > 0 { + primaryCategory = bid.Cat[0] + } + + return &openrtb_ext.ExtBidPrebidVideo{ + Duration: int(bid.Dur), + PrimaryCategory: primaryCategory, + } +} + func makeImps(imp openrtb2.Imp) (openrtb2.Imp, string, string, error) { var bidderExt adapters.ExtImpBidder if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { @@ -229,13 +319,13 @@ func makeImps(imp openrtb2.Imp) (openrtb2.Imp, string, string, error) { // Validate Video if it exists if imp.Video != nil { if err := validateVideoParams(imp.Video); err != nil { - return openrtb2.Imp{}, insticatorExt.AdUnitId, insticatorExt.PublisherId, &errortypes.BadInput{ + return openrtb2.Imp{}, "", insticatorExt.PublisherId, &errortypes.BadInput{ Message: err.Error(), } } } - // Return the imp, AdUnitId, and no error + // Return the imp, adUnitId as groupKey, publisherId, and no error return imp, insticatorExt.AdUnitId, insticatorExt.PublisherId, nil } diff --git a/adapters/insticator/insticator_test.go b/adapters/insticator/insticator_test.go index b557aedce4..6e80fa4eac 100644 --- a/adapters/insticator/insticator_test.go +++ b/adapters/insticator/insticator_test.go @@ -3,14 +3,16 @@ package insticator 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderInsticator, config.Adapter{ - Endpoint: "https://insticator.example.com/v1/pbs"}, + Endpoint: "https://insticator.example.com/v1/pbs", + ExtraAdapterInfo: `{"app_endpoint": "https://insticator-app.example.com/v1/pbs"}`, + }, config.Server{ExternalUrl: "https://insticator.example.com/v1/pbs", GvlID: 1, DataCenter: "2"}) if buildErr != nil { diff --git a/adapters/insticator/insticatortest/exemplary/app-banner.json b/adapters/insticator/insticatortest/exemplary/app-banner.json index 4c71760a73..443dde561d 100644 --- a/adapters/insticator/insticatortest/exemplary/app-banner.json +++ b/adapters/insticator/insticatortest/exemplary/app-banner.json @@ -1,85 +1,103 @@ { - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "bidder": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } + ] + }, + "ext": { + "bidder": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } - ], - "app": { - "publisher": { - "id": "test-publisher-id" - } - }, - "device": { - "ua": "", - "ip": "1.1.1.2", - "ipv6": "" + } + ], + "app": { + "publisher": { + "id": "test-publisher-id" } }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", - "body": { - "device":{ - "ip": "1.1.1.2" - }, - "ext": { - "insticator": { - "caller": [ + "device": { + "ua": "", + "ip": "1.1.1.2", + "ipv6": "" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://insticator-app.example.com/v1/pbs?publisherId=test-publisher-id", + "body": { + "device": { + "ip": "1.1.1.2" + }, + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ { - "name": "Prebid-Server", - "version": "n/a" + "w": 728, + "h": 90 } ] - } - }, - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "insticator": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } + }, + "ext": { + "insticator": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } - ], - "app": { - "publisher": { - "id": "test-publisher-id" - } } - }, - "impIDs":["test-imp-id"] + ], + "app": { + "publisher": { + "id": "test-publisher-id" + } + } }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "insticator", - "bid": [{ + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "insticator", + "bid": [ + { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", - "price": 0.500000, + "price": 0.5, "adm": "some-test-ad", + "adomain": [ + "insticator.com" + ], + "cat": [ + "IAB1" + ], "crid": "crid_10", "h": 90, "w": 728, @@ -89,39 +107,51 @@ "mediaType": "banner" } } - }] - } - ], - "cur": "USD" - } + } + ] + } + ], + "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": "crid_10", - "w": 728, - "h": 90, - "mtype": 1, - "ext": { - "insticator": { - "mediaType": "banner" - } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adomain": [ + "insticator.com" + ], + "cat": [ + "IAB1" + ], + "crid": "crid_10", + "w": 728, + "h": 90, + "mtype": 1, + "ext": { + "insticator": { + "mediaType": "banner" } - }, - "type": "banner" - } - ] - } - ] - } - \ No newline at end of file + } + }, + "BidMeta": { + "advertiserDomains": [ + "insticator.com" + ], + "mediaType": "banner", + "primaryCatId": "IAB1" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/insticator/insticatortest/exemplary/app-video.json b/adapters/insticator/insticatortest/exemplary/app-video.json index 2f0143fe96..6173802b15 100644 --- a/adapters/insticator/insticatortest/exemplary/app-video.json +++ b/adapters/insticator/insticatortest/exemplary/app-video.json @@ -59,7 +59,7 @@ "1.22.22.1" ] }, - "uri": "https://insticator.example.com/v1/pbs", + "uri": "https://insticator-app.example.com/v1/pbs?publisherId=test-publisher-id", "body": { "device": { "ip": "1.22.22.1", @@ -125,8 +125,15 @@ { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", - "price": 0.500000, + "price": 0.5, "adm": "some-test-vast-ad", + "adomain": [ + "insticator.com" + ], + "cat": [ + "IAB1-1" + ], + "dur": 30, "mtype": 2, "crid": "crid_10", "h": 90, @@ -155,6 +162,13 @@ "impid": "test-imp-id", "price": 0.5, "adm": "some-test-vast-ad", + "adomain": [ + "insticator.com" + ], + "cat": [ + "IAB1-1" + ], + "dur": 30, "crid": "crid_10", "w": 728, "mtype": 2, @@ -165,9 +179,20 @@ } } }, + "BidMeta": { + "advertiserDomains": [ + "insticator.com" + ], + "mediaType": "video", + "primaryCatId": "IAB1-1" + }, + "BidVideo": { + "duration": 30, + "primary_category": "IAB1-1" + }, "type": "video" } ] } ] -} \ No newline at end of file +} diff --git a/adapters/insticator/insticatortest/exemplary/multi-format.json b/adapters/insticator/insticatortest/exemplary/multi-format.json index 1fedfe8dc9..2efb075a39 100644 --- a/adapters/insticator/insticatortest/exemplary/multi-format.json +++ b/adapters/insticator/insticatortest/exemplary/multi-format.json @@ -1,121 +1,146 @@ { - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "video": { - "w": 728, - "h": 90, - "protocols": [2], - "playbackmethod": [2], - "mimes": ["foo", "bar"] - }, - "ext": { - "bidder": { - "adUnitId": "inview", - "publisherId": "test-publisher-id" + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } + ] + }, + "video": { + "w": 728, + "h": 90, + "protocols": [ + 2 + ], + "playbackmethod": [ + 2 + ], + "mimes": [ + "foo", + "bar" + ] + }, + "ext": { + "bidder": { + "adUnitId": "inview", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } } - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", - "body": { - "ext": { - "insticator": { - "caller": [ + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://insticator.example.com/v1/pbs?publisherId=test-publisher-id", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ { - "name": "Prebid-Server", - "version": "n/a" + "w": 728, + "h": 90 } ] - } - }, - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "video": { - "w": 728, - "h": 90, - "protocols": [2], - "playbackmethod": [2], - "mimes": ["foo", "bar"] - }, - "ext": { - "insticator": { - "adUnitId": "inview", - "publisherId": "test-publisher-id" - } + }, + "video": { + "w": 728, + "h": 90, + "protocols": [ + 2 + ], + "playbackmethod": [ + 2 + ], + "mimes": [ + "foo", + "bar" + ] + }, + "ext": { + "insticator": { + "adUnitId": "inview", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } } - }, - "impIDs":["test-imp-id"] + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "insticator", - "bid": [{ + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "insticator", + "bid": [ + { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", - "price": 0.500000, + "price": 0.5, "adm": "some-test-ad", "crid": "crid_10", "h": 90, "w": 728 - }] - } - ], - "cur": "USD" - } + } + ] + } + ], + "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": "crid_10", - "w": 728, - "h": 90 - }, - "type": "banner" - } - ] - } - ] - } - \ No newline at end of file + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/insticator/insticatortest/exemplary/multi-imps.json b/adapters/insticator/insticatortest/exemplary/multi-imps.json index eb744ced11..794c34bfbb 100644 --- a/adapters/insticator/insticatortest/exemplary/multi-imps.json +++ b/adapters/insticator/insticatortest/exemplary/multi-imps.json @@ -1,137 +1,175 @@ { - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id1", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "bidder": { - "adUnitId": "inview", - "publisherId": "test-publisher-id" + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id1", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } - } + ] }, - { - "id": "test-imp-id2", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "bidder": { - "adUnitId": "inview", - "publisherId": "test-publisher-id" - } + "ext": { + "bidder": { + "adUnitId": "inview", + "publisherId": "test-publisher-id" } - }, - { - "id": "test-imp-id3", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "bidder": { - "adUnitId": "inview", - "publisherId": "test-publisher-id" + } + }, + { + "id": "test-imp-id2", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } - } + ] }, - { - "id": "test-imp-id4", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "bidder": { - "adUnitId": "siab", - "publisherId": "test-publisher-id" + "ext": { + "bidder": { + "adUnitId": "inview", + "publisherId": "test-publisher-id" + } + } + }, + { + "id": "test-imp-id3", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } + ] + }, + "ext": { + "bidder": { + "adUnitId": "inview", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" + }, + { + "id": "test-imp-id4", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "adUnitId": "siab", + "publisherId": "test-publisher-id" + } } } - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", - "body": { - "ext": { - "insticator": { - "caller": [ + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://insticator.example.com/v1/pbs?publisherId=test-publisher-id", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id1", + "banner": { + "format": [ { - "name": "Prebid-Server", - "version": "n/a" + "w": 728, + "h": 90 } ] + }, + "ext": { + "insticator": { + "adUnitId": "inview", + "publisherId": "test-publisher-id" + } } }, - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id1", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "insticator": { - "adUnitId": "inview", - "publisherId": "test-publisher-id" + { + "id": "test-imp-id2", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } - } + ] }, - { - "id":"test-imp-id2", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "insticator": { - "adUnitId": "inview", - "publisherId": "test-publisher-id" - } + "ext": { + "insticator": { + "adUnitId": "inview", + "publisherId": "test-publisher-id" } - }, - { - "id":"test-imp-id3", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "insticator": { - "adUnitId": "inview", - "publisherId": "test-publisher-id" + } + }, + { + "id": "test-imp-id3", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } + ] + }, + "ext": { + "insticator": { + "adUnitId": "inview", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } } - }, - "impIDs":["test-imp-id1","test-imp-id2", "test-imp-id3"] + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "insticator", - "bid": [ - { + "impIDs": [ + "test-imp-id1", + "test-imp-id2", + "test-imp-id3" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "insticator", + "bid": [ + { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id1", - "price": 0.500000, + "price": 0.5, "adm": "some-test-ad", "crid": "crid_10", "h": 90, @@ -141,91 +179,98 @@ "mediaType": "banner" } } - }, - { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id2", - "price": 0.600000, - "adm": "some-test-ad", - "crid": "crid_10", - "h": 90, - "w": 728, - "ext": { - "insticator": { - "mediaType": "banner" - } + }, + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id2", + "price": 0.6, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "insticator": { + "mediaType": "banner" } - }, - { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id3", - "price": 0.500000, - "adm": "some-test-ad", - "crid": "crid_10", - "h": 90, - "w": 728, - "ext": { - "insticator": { - "mediaType": "banner" - } + } + }, + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id3", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "insticator": { + "mediaType": "banner" } } - ] - } - ], - "cur": "USD" - } + } + ] + } + ], + "cur": "USD" } - }, - { - "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", - "body": { - "ext": { - "insticator": { - "caller": [ + } + }, + { + "expectedRequest": { + "uri": "https://insticator.example.com/v1/pbs?publisherId=test-publisher-id", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id4", + "banner": { + "format": [ { - "name": "Prebid-Server", - "version": "n/a" + "w": 728, + "h": 90 } ] - } - }, - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id4", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "insticator": { - "adUnitId": "siab", - "publisherId": "test-publisher-id" - } + }, + "ext": { + "insticator": { + "adUnitId": "siab", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } } - }, - "impIDs":["test-imp-id4"] + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "insticator", - "bid": [ - { + "impIDs": [ + "test-imp-id4" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "insticator", + "bid": [ + { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id4", - "price": 0.500000, + "impid": "test-imp-id4", + "price": 0.5, "adm": "some-test-ad", "crid": "crid_10", "h": 90, @@ -235,95 +280,93 @@ "mediaType": "banner" } } - } - ] - } - ], - "cur": "USD" - } + } + ] + } + ], + "cur": "USD" } } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id1", - "price": 0.5, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 728, - "h": 90, - "ext": { - "insticator": { - "mediaType": "banner" - } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "insticator": { + "mediaType": "banner" } - }, - "type": "banner" + } }, - { - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id2", - "price": 0.6, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 728, - "h": 90, - "ext": { - "insticator": { - "mediaType": "banner" - } + "type": "banner" + }, + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id2", + "price": 0.6, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "insticator": { + "mediaType": "banner" } - }, - "type": "banner" + } }, - { - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id3", - "price": 0.5, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 728, - "h": 90, - "ext": { - "insticator": { - "mediaType": "banner" - } + "type": "banner" + }, + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id3", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "insticator": { + "mediaType": "banner" } - }, - "type": "banner" - } - ] - }, - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id4", - "price": 0.5, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 728, - "h": 90, - "ext": { - "insticator": { - "mediaType": "banner" - } + } + }, + "type": "banner" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id4", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "insticator": { + "mediaType": "banner" } - }, - "type": "banner" - } - ] - } - ] - } - \ No newline at end of file + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/insticator/insticatortest/exemplary/site-banner.json b/adapters/insticator/insticatortest/exemplary/site-banner.json index 4586fdc176..ada1c6c7c0 100644 --- a/adapters/insticator/insticatortest/exemplary/site-banner.json +++ b/adapters/insticator/insticatortest/exemplary/site-banner.json @@ -47,7 +47,7 @@ "2001:0db8:85a3:0000:0000:8a2e:0370:7334" ] }, - "uri": "https://insticator.example.com/v1/pbs", + "uri": "https://insticator.example.com/v1/pbs?publisherId=test-publisher-id", "body": { "device": { "ipv6": "2001:0db8:85a3:0000:0000:8a2e:0370:7334", @@ -104,8 +104,14 @@ { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", - "price": 0.500000, + "price": 0.5, "adm": "some-test-ad", + "adomain": [ + "insticator.com" + ], + "cat": [ + "IAB1" + ], "crid": "crid_10", "h": 90, "w": 728, @@ -134,6 +140,12 @@ "impid": "test-imp-id", "price": 0.5, "adm": "some-test-ad", + "adomain": [ + "insticator.com" + ], + "cat": [ + "IAB1" + ], "crid": "crid_10", "w": 728, "h": 90, @@ -144,9 +156,16 @@ } } }, + "BidMeta": { + "advertiserDomains": [ + "insticator.com" + ], + "mediaType": "banner", + "primaryCatId": "IAB1" + }, "type": "banner" } ] } ] -} \ No newline at end of file +} diff --git a/adapters/insticator/insticatortest/exemplary/site-video.json b/adapters/insticator/insticatortest/exemplary/site-video.json index bd7c40af20..0e7b404ba6 100644 --- a/adapters/insticator/insticatortest/exemplary/site-video.json +++ b/adapters/insticator/insticatortest/exemplary/site-video.json @@ -5,13 +5,20 @@ { "id": "test-imp-id", "video": { - "w": 728, + "w": 728, "h": 90, - "protocols": [2], + "protocols": [ + 2 + ], "placement": 1, "startdelay": -2, - "playbackmethod": [2], - "mimes": ["foo", "bar"] + "playbackmethod": [ + 2 + ], + "mimes": [ + "foo", + "bar" + ] }, "ext": { "bidder": { @@ -27,11 +34,10 @@ } } }, - "httpCalls": [ { "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", + "uri": "https://insticator.example.com/v1/pbs?publisherId=test-publisher-id", "body": { "ext": { "insticator": { @@ -46,15 +52,22 @@ "id": "test-request-id", "imp": [ { - "id":"test-imp-id", + "id": "test-imp-id", "video": { - "w": 728, + "w": 728, "h": 90, - "protocols": [2], + "protocols": [ + 2 + ], "placement": 1, "startdelay": -2, - "playbackmethod": [2], - "mimes": ["foo", "bar"] + "playbackmethod": [ + 2 + ], + "mimes": [ + "foo", + "bar" + ] }, "ext": { "insticator": { @@ -70,7 +83,9 @@ } } }, - "impIDs":["test-imp-id"] + "impIDs": [ + "test-imp-id" + ] }, "mockResponse": { "status": 200, @@ -79,21 +94,30 @@ "seatbid": [ { "seat": "insticator", - "bid": [{ - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 0.500000, - "adm": "some-test-vast-ad", - "mtype": 2, - "crid": "crid_10", - "h": 90, - "w": 728, - "ext": { - "insticator": { - "mediaType": "video" + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-vast-ad", + "adomain": [ + "insticator.com" + ], + "cat": [ + "IAB1-1" + ], + "dur": 30, + "mtype": 2, + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "insticator": { + "mediaType": "video" + } } } - }] + ] } ], "cur": "USD" @@ -101,7 +125,6 @@ } } ], - "expectedBidResponses": [ { "currency": "USD", @@ -112,6 +135,13 @@ "impid": "test-imp-id", "price": 0.5, "adm": "some-test-vast-ad", + "adomain": [ + "insticator.com" + ], + "cat": [ + "IAB1-1" + ], + "dur": 30, "crid": "crid_10", "w": 728, "mtype": 2, @@ -122,6 +152,17 @@ } } }, + "BidMeta": { + "advertiserDomains": [ + "insticator.com" + ], + "mediaType": "video", + "primaryCatId": "IAB1-1" + }, + "BidVideo": { + "duration": 30, + "primary_category": "IAB1-1" + }, "type": "video" } ] diff --git a/adapters/insticator/insticatortest/supplemental/204.json b/adapters/insticator/insticatortest/supplemental/204.json index f0a43defb1..e2a7ef5787 100644 --- a/adapters/insticator/insticatortest/supplemental/204.json +++ b/adapters/insticator/insticatortest/supplemental/204.json @@ -1,71 +1,81 @@ { - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "bidder": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } + ] + }, + "ext": { + "bidder": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } } - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", - "body": { - "ext": { - "insticator": { - "caller": [ + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://insticator.example.com/v1/pbs?publisherId=test-publisher-id", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ { - "name": "Prebid-Server", - "version": "n/a" + "w": 728, + "h": 90 } ] - } - }, - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "insticator": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } + }, + "ext": { + "insticator": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } } - }, - "impIDs":["test-imp-id"] + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, - "mockResponse": { - "status": 204, - "body": {} - } + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 204, + "body": {} } - ], - "expectedBidResponses": [] - } - \ No newline at end of file + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/insticator/insticatortest/supplemental/app-pubid-absent.json b/adapters/insticator/insticatortest/supplemental/app-pubid-absent.json index 0fcafa58b1..5efc22fa3c 100644 --- a/adapters/insticator/insticatortest/supplemental/app-pubid-absent.json +++ b/adapters/insticator/insticatortest/supplemental/app-pubid-absent.json @@ -1,77 +1,89 @@ { - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "bidder": { - "adUnitId": "fake-app-id", - "publisherId": "test-publisher-id" + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } + ] + }, + "ext": { + "bidder": { + "adUnitId": "fake-app-id", + "publisherId": "test-publisher-id" } } - ], - "app": { - "id": "test-app-id", - "bundle": "test-app.com" + } + ], + "app": { + "id": "test-app-id", + "bundle": "test-app.com" } - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", - "body": { - "ext": { - "insticator": { - "caller": [ + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://insticator-app.example.com/v1/pbs?publisherId=test-publisher-id", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ { - "name": "Prebid-Server", - "version": "n/a" + "w": 728, + "h": 90 } ] - } - }, - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "insticator": { - "adUnitId": "fake-app-id", - "publisherId": "test-publisher-id" - } + }, + "ext": { + "insticator": { + "adUnitId": "fake-app-id", + "publisherId": "test-publisher-id" } } - ], - "app": { + } + ], + "app": { "id": "test-app-id", "bundle": "test-app.com", - "publisher": { - "id": "test-publisher-id" - } + "publisher": { + "id": "test-publisher-id" } - }, - "impIDs":["test-imp-id"] + } }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "insticator", - "bid": [{ + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "insticator", + "bid": [ + { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", - "price": 0.500000, + "price": 0.5, "adm": "some-test-ad", "crid": "crid_10", "h": 90, @@ -82,39 +94,38 @@ "mediaType": "banner" } } - }] - } - ], - "cur": "USD" - } + } + ] + } + ], + "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": "crid_10", - "w": 728, - "h": 90, - "mtype": 1, - "ext": { - "insticator": { - "mediaType": "banner" - } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "mtype": 1, + "ext": { + "insticator": { + "mediaType": "banner" } - }, - "type": "banner" - } - ] - } - ] - } - \ No newline at end of file + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/insticator/insticatortest/supplemental/bad-imp-ext.json b/adapters/insticator/insticatortest/supplemental/bad-imp-ext.json index 2e0507791a..71727e03f4 100644 --- a/adapters/insticator/insticatortest/supplemental/bad-imp-ext.json +++ b/adapters/insticator/insticatortest/supplemental/bad-imp-ext.json @@ -1,29 +1,32 @@ { - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "bidder": "invalid ext" - } - } - ], - "site": { - "publisher": { - "id": "test-publisher-id" + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": "invalid ext" } } - }, - - "expectedMakeRequestsErrors": [ - { - "value": "expect { or n, but found \"", - "comparison": "literal" - } - ] - } - \ No newline at end of file + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/insticator/insticatortest/supplemental/currency-conversion-fail.json b/adapters/insticator/insticatortest/supplemental/currency-conversion-fail.json index 4c7082f47d..1bdc9587da 100644 --- a/adapters/insticator/insticatortest/supplemental/currency-conversion-fail.json +++ b/adapters/insticator/insticatortest/supplemental/currency-conversion-fail.json @@ -1,49 +1,49 @@ { - "mockBidRequest": { - "cur": [ - "GBP" - ], - "id": "test-request-id", - "imp": [ + "mockBidRequest": { + "cur": [ + "GBP" + ], + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 728, - "h": 90 - } - ] - }, - "ext": { - "bidder": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } - }, - "bidfloor": 1, - "bidfloorcur": "GBP" - } - ], - "site": { - "publisher": { - "id": "test-publisher-id" + "w": 728, + "h": 90 } + ] }, "ext": { - "prebid": { - "currency": { - "rates": { - "INR": { - "USD": 2 - } - }, - "usepbsrates": false - } + "bidder": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" + } + }, + "bidfloor": 1, + "bidfloorcur": "GBP" + } + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + }, + "ext": { + "prebid": { + "currency": { + "rates": { + "INR": { + "USD": 2 } + }, + "usepbsrates": false } - }, - "expectedMakeRequestsErrors": [ + } + } + }, + "expectedMakeRequestsErrors": [ { "value": "Error in converting the provided bid floor currency from GBP to USD", "comparison": "literal" diff --git a/adapters/insticator/insticatortest/supplemental/currency-conversion.json b/adapters/insticator/insticatortest/supplemental/currency-conversion.json index 9ce11dcdfb..a067eac721 100644 --- a/adapters/insticator/insticatortest/supplemental/currency-conversion.json +++ b/adapters/insticator/insticatortest/supplemental/currency-conversion.json @@ -1,152 +1,152 @@ { - "mockBidRequest": { - "cur": [ - "GBP" - ], - "id": "test-request-id", - "imp": [ + "mockBidRequest": { + "cur": [ + "GBP" + ], + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 728, - "h": 90 - } - ] - }, - "ext": { - "bidder": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } - }, - "bidfloor": 1, - "bidfloorcur": "GBP" - } - ], - "site": { - "publisher": { - "id": "test-publisher-id" + "w": 728, + "h": 90 } + ] }, "ext": { - "prebid": { - "currency": { - "rates": { - "GBP": { - "USD": 2 - } - }, - "usepbsrates": false - } + "bidder": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" + } + }, + "bidfloor": 1, + "bidfloorcur": "GBP" + } + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + }, + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 2 } + }, + "usepbsrates": false } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", - "body": { - "cur": [ - "GBP" - ], - "ext": { - "insticator": { - "caller": [ - { - "name": "Prebid-Server", - "version": "n/a" - } - ] - } - }, - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 728, - "h": 90 - } - ] - }, - "ext": { - "insticator": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } - }, - "bidfloor": 2, - "bidfloorcur": "USD" - } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } - } - }, - "impIDs": [ - "test-imp-id" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://insticator.example.com/v1/pbs?publisherId=test-publisher-id", + "body": { + "cur": [ + "GBP" + ], + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } ] - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "insticator", - "bid": [ - { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 0.500000, - "adm": "some-test-ad", - "crid": "crid_10", - "h": 90, - "w": 728, - "mtype": 1, - "ext": { - "insticator": { - "mediaType": "banner" - } - } - } - ] - } - ], - "cur": "USD" + }, + "ext": { + "insticator": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } + }, + "bidfloor": 2, + "bidfloorcur": "USD" } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "insticator", + "bid": [ { - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 0.5, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 728, - "h": 90, - "mtype": 1, - "ext": { - "insticator": { - "mediaType": "banner" - } - } - }, - "type": "banner" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1, + "ext": { + "insticator": { + "mediaType": "banner" + } + } } - ] + ] + } + ], + "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": "crid_10", + "w": 728, + "h": 90, + "mtype": 1, + "ext": { + "insticator": { + "mediaType": "banner" + } + } + }, + "type": "banner" } - ] -} \ No newline at end of file + ] + } + ] +} diff --git a/adapters/insticator/insticatortest/supplemental/device-validation.json b/adapters/insticator/insticatortest/supplemental/device-validation.json index a493e1b28a..b6901f9177 100644 --- a/adapters/insticator/insticatortest/supplemental/device-validation.json +++ b/adapters/insticator/insticatortest/supplemental/device-validation.json @@ -56,7 +56,7 @@ "1.22.22.1" ] }, - "uri": "https://insticator.example.com/v1/pbs", + "uri": "https://insticator-app.example.com/v1/pbs?publisherId=test-publisher-id", "body": { "device": { "ip": "1.22.22.1" @@ -120,7 +120,7 @@ { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", - "price": 0.500000, + "price": 0.5, "adm": "some-test-vast-ad", "mtype": 2, "crid": "crid_10", @@ -165,4 +165,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json index 18fa069aed..8ea638fcee 100644 --- a/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json +++ b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json @@ -1,110 +1,137 @@ { - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id1", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "bidder": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id1", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } - } + ] }, - { - "id": "test-imp-id2", - "video": { - "mimes": ["video/mp4"], - "minduration": 5, - "maxduration": 30, - "protocols": [2, 3, 5, 6], - "w": 640, - "h": 480 - }, - "ext": { - "bidder": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } + "ext": { + "bidder": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" + }, + { + "id": "test-imp-id2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 5, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" + } } } - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", - "body": { - "ext": { - "insticator": { - "caller": [ + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://insticator.example.com/v1/pbs?publisherId=test-publisher-id", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id1", + "banner": { + "format": [ { - "name": "Prebid-Server", - "version": "n/a" + "w": 728, + "h": 90 } ] + }, + "ext": { + "insticator": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" + } } }, - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id1", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "insticator": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } - } + { + "id": "test-imp-id2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 5, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 640, + "h": 480 }, - { - "id":"test-imp-id2", - "video": { - "mimes": ["video/mp4"], - "minduration": 5, - "maxduration": 30, - "protocols": [2, 3, 5, 6], - "w": 640, - "h": 480 - }, - "ext": { - "insticator": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } + "ext": { + "insticator": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } } - }, - "impIDs":["test-imp-id1", "test-imp-id2"] + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "insticator", - "bid": [{ + "impIDs": [ + "test-imp-id1", + "test-imp-id2" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "insticator", + "bid": [ + { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id1", - "price": 0.500000, + "price": 0.5, "adm": "some-test-ad", "crid": "crid_10", "h": 90, @@ -115,38 +142,38 @@ "mediaType": "banner" } } - }] - } - ], - "cur": "USD" - } + } + ] + } + ], + "cur": "USD" } } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id1", - "price": 0.5, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 728, - "h": 90, - "mtype": 1, - "ext": { - "insticator": { - "mediaType": "banner" - } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "mtype": 1, + "ext": { + "insticator": { + "mediaType": "banner" } - }, - "type": "banner" - } - ] - } - ] - } - \ No newline at end of file + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/insticator/insticatortest/supplemental/request-ext-unmarshal-fail.json b/adapters/insticator/insticatortest/supplemental/request-ext-unmarshal-fail.json index 1ea883a11c..3a99a142a1 100644 --- a/adapters/insticator/insticatortest/supplemental/request-ext-unmarshal-fail.json +++ b/adapters/insticator/insticatortest/supplemental/request-ext-unmarshal-fail.json @@ -1,17 +1,24 @@ { -"mockBidRequest": { + "mockBidRequest": { "id": "test-request-id", "imp": [ { "id": "test-imp-id", "video": { - "w": 728, + "w": 728, "h": 90, - "protocols": [2], + "protocols": [ + 2 + ], "placement": 1, "startdelay": -2, - "playbackmethod": [2], - "mimes": ["foo", "bar"] + "playbackmethod": [ + 2 + ], + "mimes": [ + "foo", + "bar" + ] }, "ext": { "bidder": "invalid" @@ -24,18 +31,17 @@ } }, "ext": { - "insticator": "invalid" + "insticator": "invalid" } }, - - "expectedMakeRequestsErrors": [ - { - "value": "cannot unmarshal insticator.reqExt.Insticator: expect { or n, but found \"", - "comparison": "literal" - }, - { - "value": "expect { or n, but found \"", - "comparison": "literal" - } - ] + "expectedMakeRequestsErrors": [ + { + "value": "cannot unmarshal insticator.reqExt.Insticator: expect { or n, but found \"", + "comparison": "literal" + }, + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] } \ No newline at end of file diff --git a/adapters/insticator/insticatortest/supplemental/response-unmarshal-fail.json b/adapters/insticator/insticatortest/supplemental/response-unmarshal-fail.json index a3b40b084e..7ae1059b9c 100644 --- a/adapters/insticator/insticatortest/supplemental/response-unmarshal-fail.json +++ b/adapters/insticator/insticatortest/supplemental/response-unmarshal-fail.json @@ -1,102 +1,102 @@ { - "mockBidRequest": { - "id": "test-request-id", - "imp": [ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 728, + "h": 90, + "protocols": [ + 2 + ], + "placement": 1, + "startdelay": -2, + "playbackmethod": [ + 2 + ], + "mimes": [ + "foo", + "bar" + ] + }, + "ext": { + "bidder": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" + } + } + } + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://insticator.example.com/v1/pbs?publisherId=test-publisher-id", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ { - "id": "test-imp-id", - "video": { - "w": 728, - "h": 90, - "protocols": [ - 2 - ], - "placement": 1, - "startdelay": -2, - "playbackmethod": [ - 2 - ], - "mimes": [ - "foo", - "bar" - ] - }, - "ext": { - "bidder": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } + "id": "test-imp-id", + "video": { + "w": 728, + "h": 90, + "protocols": [ + 2 + ], + "placement": 1, + "startdelay": -2, + "playbackmethod": [ + 2 + ], + "mimes": [ + "foo", + "bar" + ] + }, + "ext": { + "insticator": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } + } } - ], - "site": { + ], + "site": { "publisher": { - "id": "test-publisher-id" + "id": "test-publisher-id" } - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", - "body": { - "ext": { - "insticator": { - "caller": [ - { - "name": "Prebid-Server", - "version": "n/a" - } - ] - } - }, - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 728, - "h": 90, - "protocols": [ - 2 - ], - "placement": 1, - "startdelay": -2, - "playbackmethod": [ - 2 - ], - "mimes": [ - "foo", - "bar" - ] - }, - "ext": { - "insticator": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } - } - } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } - } - }, - "impIDs": [ - "test-imp-id" - ] - }, - "mockResponse": { - "status": 200, - "body": "invalid json" - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "expect { or n, but found \"", - "comparison": "literal" - } - ] + } + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": "invalid json" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] } \ No newline at end of file diff --git a/adapters/insticator/insticatortest/supplemental/site-pubid-absent.json b/adapters/insticator/insticatortest/supplemental/site-pubid-absent.json index 00c694a197..7b2b3c5e6e 100644 --- a/adapters/insticator/insticatortest/supplemental/site-pubid-absent.json +++ b/adapters/insticator/insticatortest/supplemental/site-pubid-absent.json @@ -1,77 +1,89 @@ { - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "bidder": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } + ] + }, + "ext": { + "bidder": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } - ], - "site": { - "id": "test-site-id", - "domain": "test-site.com" + } + ], + "site": { + "id": "test-site-id", + "domain": "test-site.com" } - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", - "body": { - "ext": { - "insticator": { - "caller": [ + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://insticator.example.com/v1/pbs?publisherId=test-publisher-id", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ { - "name": "Prebid-Server", - "version": "n/a" + "w": 728, + "h": 90 } ] - } - }, - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "insticator": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } + }, + "ext": { + "insticator": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } - ], - "site": { + } + ], + "site": { "id": "test-site-id", "domain": "test-site.com", - "publisher": { - "id": "test-publisher-id" - } + "publisher": { + "id": "test-publisher-id" } - }, - "impIDs":["test-imp-id"] + } }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "insticator", - "bid": [{ + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "insticator", + "bid": [ + { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", - "price": 0.500000, + "price": 0.5, "adm": "some-test-ad", "crid": "crid_10", "h": 90, @@ -82,39 +94,38 @@ "mediaType": "banner" } } - }] - } - ], - "cur": "USD" - } + } + ] + } + ], + "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": "crid_10", - "w": 728, - "h": 90, - "mtype": 1, - "ext": { - "insticator": { - "mediaType": "banner" - } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "mtype": 1, + "ext": { + "insticator": { + "mediaType": "banner" } - }, - "type": "banner" - } - ] - } - ] - } - \ No newline at end of file + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/insticator/insticatortest/supplemental/status-not-ok.json b/adapters/insticator/insticatortest/supplemental/status-not-ok.json index e530896e2d..374b2bca26 100644 --- a/adapters/insticator/insticatortest/supplemental/status-not-ok.json +++ b/adapters/insticator/insticatortest/supplemental/status-not-ok.json @@ -1,86 +1,95 @@ { - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "bidder": { - "adUnitId": "fake-invalid-site-id", - "publisherId": "test-publisher-id" + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 } + ] + }, + "ext": { + "bidder": { + "adUnitId": "fake-invalid-site-id", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } } - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://insticator.example.com/v1/pbs", - "body": { - "ext": { - "insticator": { - "caller": [ + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://insticator.example.com/v1/pbs?publisherId=test-publisher-id", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ { - "name": "Prebid-Server", - "version": "n/a" + "w": 728, + "h": 90 } ] - } - }, - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "banner": { - "format": [{"w": 728, "h": 90}] - }, - "ext": { - "insticator": { - "adUnitId": "fake-invalid-site-id", - "publisherId": "test-publisher-id" - } + }, + "ext": { + "insticator": { + "adUnitId": "fake-invalid-site-id", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } } - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 400, - "body": { - "error": { - "message": "Validation failed", - "details": [ - { - "message": "site.id is invalid" - } - ] + ], + "site": { + "publisher": { + "id": "test-publisher-id" + } } + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 400, + "body": { + "error": { + "message": "Validation failed", + "details": [ + { + "message": "site.id is invalid" + } + ] } } } - ], - - "expectedMakeBidsErrors": [ - { - "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", - "comparison": "literal" - } - ] - } - \ No newline at end of file + } + ], + "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/insticator/insticatortest/supplemental/video-validation-fail.json b/adapters/insticator/insticatortest/supplemental/video-validation-fail.json index 553b0f68c6..51f40f8333 100644 --- a/adapters/insticator/insticatortest/supplemental/video-validation-fail.json +++ b/adapters/insticator/insticatortest/supplemental/video-validation-fail.json @@ -1,33 +1,31 @@ { - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 728, - "h": 90 - }, - "ext": { - "bidder": { - "adUnitId": "fake-site-id", - "publisherId": "test-publisher-id" - } + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } - ], - "site": { - "publisher": { - "id": "test-publisher-id" - } } - }, - - "expectedMakeRequestsErrors": [ - { - "value": "One or more invalid or missing video field(s) w, h, mimes", - "comparison": "literal" + ], + "site": { + "publisher": { + "id": "test-publisher-id" } - ] - } - \ No newline at end of file + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "One or more invalid or missing video field(s) w, h, mimes", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/insticator/params_test.go b/adapters/insticator/params_test.go index 47d2bdf44f..85089bb1ec 100644 --- a/adapters/insticator/params_test.go +++ b/adapters/insticator/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/Insticator.json diff --git a/adapters/gothamads/gothamads.go b/adapters/intenze/intenze.go similarity index 86% rename from adapters/gothamads/gothamads.go rename to adapters/intenze/intenze.go index 7b2f247108..2a9ec562b8 100644 --- a/adapters/gothamads/gothamads.go +++ b/adapters/intenze/intenze.go @@ -1,4 +1,4 @@ -package gothamads +package intenze import ( "encoding/json" @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { @@ -81,24 +81,24 @@ func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, reqInfo *ada }}, nil } -func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtGothamAds, error) { +func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtIntenze, error) { var bidderExt adapters.ExtImpBidder if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } - var gothamadsExt openrtb_ext.ExtGothamAds - if err := jsonutil.Unmarshal(bidderExt.Bidder, &gothamadsExt); err != nil { + var intenzeExt openrtb_ext.ExtIntenze + if err := jsonutil.Unmarshal(bidderExt.Bidder, &intenzeExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } - return &gothamadsExt, nil + return &intenzeExt, nil } -func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtGothamAds) (string, error) { +func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtIntenze) (string, error) { endpointParams := macros.EndpointTemplateParams{AccountID: params.AccountID} return macros.ResolveMacros(a.endpoint, endpointParams) } diff --git a/adapters/intenze/intenze_test.go b/adapters/intenze/intenze_test.go new file mode 100644 index 0000000000..00d97a6b31 --- /dev/null +++ b/adapters/intenze/intenze_test.go @@ -0,0 +1,28 @@ +package intenze + +import ( + "testing" + + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderIntenze, config.Adapter{ + Endpoint: "http://lb-east.intenze.co/?pass={{.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, "intenzetest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderIntenze, config.Adapter{ + Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} diff --git a/adapters/gothamads/gothamadstest/exemplary/banner-app.json b/adapters/intenze/intenzetest/exemplary/banner-app.json similarity index 95% rename from adapters/gothamads/gothamadstest/exemplary/banner-app.json rename to adapters/intenze/intenzetest/exemplary/banner-app.json index 61fd85abc7..1b80ff5bf0 100644 --- a/adapters/gothamads/gothamadstest/exemplary/banner-app.json +++ b/adapters/intenze/intenzetest/exemplary/banner-app.json @@ -59,7 +59,7 @@ "123.123.123.123" ] }, - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "device": { @@ -95,7 +95,9 @@ }, "tmax": 1000 }, - "impIDs":["1"] + "impIDs": [ + "1" + ] }, "mockResponse": { "status": 200, @@ -119,7 +121,7 @@ } ], "type": "banner", - "seat": "gothamAds" + "seat": "intenze" } ], "cur": "USD" diff --git a/adapters/gothamads/gothamadstest/exemplary/banner-web.json b/adapters/intenze/intenzetest/exemplary/banner-web.json similarity index 95% rename from adapters/gothamads/gothamadstest/exemplary/banner-web.json rename to adapters/intenze/intenzetest/exemplary/banner-web.json index 0d09bbeb1f..825ee9c72c 100644 --- a/adapters/gothamads/gothamadstest/exemplary/banner-web.json +++ b/adapters/intenze/intenzetest/exemplary/banner-web.json @@ -66,7 +66,7 @@ "123.123.123.123" ] }, - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "device": { @@ -109,7 +109,10 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id1","some-impression-id2"] + "impIDs": [ + "some-impression-id1", + "some-impression-id2" + ] }, "mockResponse": { "status": 200, @@ -146,7 +149,7 @@ } ], "type": "banner", - "seat": "gothamads" + "seat": "intenze" } ], "cur": "USD" diff --git a/adapters/gothamads/gothamadstest/exemplary/native-app.json b/adapters/intenze/intenzetest/exemplary/native-app.json similarity index 96% rename from adapters/gothamads/gothamadstest/exemplary/native-app.json rename to adapters/intenze/intenzetest/exemplary/native-app.json index 16ba08b5eb..57bc6dd727 100644 --- a/adapters/gothamads/gothamadstest/exemplary/native-app.json +++ b/adapters/intenze/intenzetest/exemplary/native-app.json @@ -59,7 +59,7 @@ "123.123.123.123" ] }, - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "device": { @@ -95,7 +95,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, @@ -117,7 +119,7 @@ } ], "type": "native", - "seat": "gothamads" + "seat": "intenze" } ], "cur": "USD" diff --git a/adapters/gothamads/gothamadstest/exemplary/native-web.json b/adapters/intenze/intenzetest/exemplary/native-web.json similarity index 96% rename from adapters/gothamads/gothamadstest/exemplary/native-web.json rename to adapters/intenze/intenzetest/exemplary/native-web.json index 943871a008..31dedc4403 100644 --- a/adapters/gothamads/gothamadstest/exemplary/native-web.json +++ b/adapters/intenze/intenzetest/exemplary/native-web.json @@ -53,7 +53,7 @@ "2607:fb90:f27:4512:d800:cb23:a603:e245" ] }, - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "device": { @@ -83,7 +83,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, @@ -104,7 +106,7 @@ "mtype": 4 } ], - "seat": "gothamads" + "seat": "intenze" } ], "cur": "USD" diff --git a/adapters/gothamads/gothamadstest/exemplary/video-app.json b/adapters/intenze/intenzetest/exemplary/video-app.json similarity index 95% rename from adapters/gothamads/gothamadstest/exemplary/video-app.json rename to adapters/intenze/intenzetest/exemplary/video-app.json index ce2e289014..dd836ee34c 100644 --- a/adapters/gothamads/gothamadstest/exemplary/video-app.json +++ b/adapters/intenze/intenzetest/exemplary/video-app.json @@ -64,7 +64,7 @@ "123.123.123.123" ] }, - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "device": { @@ -105,7 +105,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, @@ -128,7 +130,7 @@ "mtype": 2 } ], - "seat": "gothamads" + "seat": "intenze" } ], "cur": "USD" diff --git a/adapters/gothamads/gothamadstest/exemplary/video-web.json b/adapters/intenze/intenzetest/exemplary/video-web.json similarity index 95% rename from adapters/gothamads/gothamadstest/exemplary/video-web.json rename to adapters/intenze/intenzetest/exemplary/video-web.json index a475fc5a0c..c8b596f06a 100644 --- a/adapters/gothamads/gothamadstest/exemplary/video-web.json +++ b/adapters/intenze/intenzetest/exemplary/video-web.json @@ -58,7 +58,7 @@ "123.123.123.123" ] }, - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "device": { @@ -93,7 +93,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, @@ -121,7 +123,7 @@ "mtype": 2 } ], - "seat": "gothamads" + "seat": "intenze" } ], "cur": "USD" diff --git a/adapters/gothamads/gothamadstest/supplemental/bad_media_type.json b/adapters/intenze/intenzetest/supplemental/bad_media_type.json similarity index 95% rename from adapters/gothamads/gothamadstest/supplemental/bad_media_type.json rename to adapters/intenze/intenzetest/supplemental/bad_media_type.json index 0079ce3e71..6b8050c0e7 100644 --- a/adapters/gothamads/gothamadstest/supplemental/bad_media_type.json +++ b/adapters/intenze/intenzetest/supplemental/bad_media_type.json @@ -59,7 +59,7 @@ "123.123.123.123" ] }, - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "device": { @@ -95,7 +95,9 @@ }, "tmax": 1000 }, - "impIDs":["1"] + "impIDs": [ + "1" + ] }, "mockResponse": { "status": 200, @@ -118,7 +120,7 @@ } ], "mtype": 0, - "seat": "gothamads" + "seat": "intenze" } ], "cur": "USD" diff --git a/adapters/gothamads/gothamadstest/supplemental/empty-seatbid-array.json b/adapters/intenze/intenzetest/supplemental/empty-seatbid-array.json similarity index 95% rename from adapters/gothamads/gothamadstest/supplemental/empty-seatbid-array.json rename to adapters/intenze/intenzetest/supplemental/empty-seatbid-array.json index 58970bd8e8..3302320c06 100644 --- a/adapters/gothamads/gothamadstest/supplemental/empty-seatbid-array.json +++ b/adapters/intenze/intenzetest/supplemental/empty-seatbid-array.json @@ -64,7 +64,7 @@ "123.123.123.123" ] }, - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "device": { @@ -105,7 +105,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, diff --git a/adapters/gothamads/gothamadstest/supplemental/invalid-bidder-ext-object.json b/adapters/intenze/intenzetest/supplemental/invalid-bidder-ext-object.json similarity index 100% rename from adapters/gothamads/gothamadstest/supplemental/invalid-bidder-ext-object.json rename to adapters/intenze/intenzetest/supplemental/invalid-bidder-ext-object.json diff --git a/adapters/gothamads/gothamadstest/supplemental/invalid-gotham-ext-object.json b/adapters/intenze/intenzetest/supplemental/invalid-intenze-ext-object.json similarity index 100% rename from adapters/gothamads/gothamadstest/supplemental/invalid-gotham-ext-object.json rename to adapters/intenze/intenzetest/supplemental/invalid-intenze-ext-object.json diff --git a/adapters/gothamads/gothamadstest/supplemental/invalid-response.json b/adapters/intenze/intenzetest/supplemental/invalid-response.json similarity index 94% rename from adapters/gothamads/gothamadstest/supplemental/invalid-response.json rename to adapters/intenze/intenzetest/supplemental/invalid-response.json index fe9cb3fd38..585ea65963 100644 --- a/adapters/gothamads/gothamadstest/supplemental/invalid-response.json +++ b/adapters/intenze/intenzetest/supplemental/invalid-response.json @@ -59,7 +59,7 @@ "123.123.123.123" ] }, - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "device": { @@ -95,7 +95,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, diff --git a/adapters/gothamads/gothamadstest/supplemental/status-code-bad-request.json b/adapters/intenze/intenzetest/supplemental/status-code-bad-request.json similarity index 94% rename from adapters/gothamads/gothamadstest/supplemental/status-code-bad-request.json rename to adapters/intenze/intenzetest/supplemental/status-code-bad-request.json index b0e2a09855..746a56355b 100644 --- a/adapters/gothamads/gothamadstest/supplemental/status-code-bad-request.json +++ b/adapters/intenze/intenzetest/supplemental/status-code-bad-request.json @@ -41,7 +41,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "imp": [ @@ -76,7 +76,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 400 diff --git a/adapters/gothamads/gothamadstest/supplemental/status-code-no-content.json b/adapters/intenze/intenzetest/supplemental/status-code-no-content.json similarity index 92% rename from adapters/gothamads/gothamadstest/supplemental/status-code-no-content.json rename to adapters/intenze/intenzetest/supplemental/status-code-no-content.json index 97fbc419af..ad8a50ccc1 100644 --- a/adapters/gothamads/gothamadstest/supplemental/status-code-no-content.json +++ b/adapters/intenze/intenzetest/supplemental/status-code-no-content.json @@ -35,7 +35,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "imp": [ @@ -64,7 +64,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 204 diff --git a/adapters/gothamads/gothamadstest/supplemental/status-code-other-error.json b/adapters/intenze/intenzetest/supplemental/status-code-other-error.json similarity index 93% rename from adapters/gothamads/gothamadstest/supplemental/status-code-other-error.json rename to adapters/intenze/intenzetest/supplemental/status-code-other-error.json index 5d1916cce7..59ef26aa88 100644 --- a/adapters/gothamads/gothamadstest/supplemental/status-code-other-error.json +++ b/adapters/intenze/intenzetest/supplemental/status-code-other-error.json @@ -35,7 +35,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "imp": [ @@ -64,7 +64,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 306 diff --git a/adapters/gothamads/gothamadstest/supplemental/status-code-service-unavailable.json b/adapters/intenze/intenzetest/supplemental/status-code-service-unavailable.json similarity index 92% rename from adapters/gothamads/gothamadstest/supplemental/status-code-service-unavailable.json rename to adapters/intenze/intenzetest/supplemental/status-code-service-unavailable.json index e69644e967..138865eefb 100644 --- a/adapters/gothamads/gothamadstest/supplemental/status-code-service-unavailable.json +++ b/adapters/intenze/intenzetest/supplemental/status-code-service-unavailable.json @@ -35,7 +35,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "uri": "http://lb-east.intenze.co/?pass=accountId", "body": { "id": "some-request-id", "imp": [ @@ -64,7 +64,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 503 diff --git a/adapters/gothamads/params_test.go b/adapters/intenze/params_test.go similarity index 71% rename from adapters/gothamads/params_test.go rename to adapters/intenze/params_test.go index ff61796deb..51fbd2dc38 100644 --- a/adapters/gothamads/params_test.go +++ b/adapters/intenze/params_test.go @@ -1,10 +1,10 @@ -package gothamads +package intenze import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ @@ -18,8 +18,8 @@ func TestValidParams(t *testing.T) { } for _, validParam := range validParams { - if err := validator.Validate(openrtb_ext.BidderGothamads, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected Gothamads params: %s", validParam) + if err := validator.Validate(openrtb_ext.BidderIntenze, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected Intenze params: %s", validParam) } } } @@ -43,7 +43,7 @@ func TestInvalidParams(t *testing.T) { } for _, invalidParam := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderGothamads, json.RawMessage(invalidParam)); err == nil { + if err := validator.Validate(openrtb_ext.BidderIntenze, json.RawMessage(invalidParam)); err == nil { t.Errorf("Schema allowed unexpected params: %s", invalidParam) } } diff --git a/adapters/interactiveoffers/interactiveoffers.go b/adapters/interactiveoffers/interactiveoffers.go index 6eaee7a978..3c3d750bbb 100644 --- a/adapters/interactiveoffers/interactiveoffers.go +++ b/adapters/interactiveoffers/interactiveoffers.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/interactiveoffers/interactiveoffers_test.go b/adapters/interactiveoffers/interactiveoffers_test.go index df116c60a5..16c5eeb958 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/interactiveoffers/params_test.go b/adapters/interactiveoffers/params_test.go index 631d8f44ae..cb15379164 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/intertech/intertech.go b/adapters/intertech/intertech.go deleted file mode 100644 index ae491995a7..0000000000 --- a/adapters/intertech/intertech.go +++ /dev/null @@ -1,226 +0,0 @@ -package intertech - -import ( - "fmt" - "net/http" - "net/url" - "strconv" - "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" -) - -const ( - pageIDMacro = "{{page_id}}" - impIDMacro = "{{imp_id}}" -) - -type adapter struct { - endpoint string -} - -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 requests []*adapters.RequestData - - referer := getReferer(request) - cur := getCur(request) - - for _, imp := range request.Imp { - extImp, err := parseAndValidateImpExt(imp) - if err != nil { - errs = append(errs, err) - continue - } - - modifiedImp, err := modifyImp(imp) - if err != nil { - errs = append(errs, err) - continue - } - - modifiedUrl := a.modifyUrl(extImp, referer, cur) - - modRequest := *request - modRequest.Imp = []openrtb2.Imp{modifiedImp} - - reqData, err := buildRequestData(modRequest, modifiedUrl) - if err != nil { - errs = append(errs, err) - continue - } - - requests = append(requests, reqData) - } - - return requests, errs -} - -func parseAndValidateImpExt(imp openrtb2.Imp) (openrtb_ext.ExtImpIntertech, error) { - var bidderExt adapters.ExtImpBidder - if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { - return openrtb_ext.ExtImpIntertech{}, &errortypes.BadInput{ - Message: fmt.Sprintf("imp #%s: unable to parse bidder ext: %s", imp.ID, err), - } - } - - var extImp openrtb_ext.ExtImpIntertech - if err := jsonutil.Unmarshal(bidderExt.Bidder, &extImp); err != nil { - return openrtb_ext.ExtImpIntertech{}, &errortypes.BadInput{ - Message: fmt.Sprintf("imp #%s: unable to parse intertech ext: %s", imp.ID, err), - } - } - - return extImp, nil -} - -func modifyImp(imp openrtb2.Imp) (openrtb2.Imp, error) { - if imp.Banner != nil { - banner, err := updateBanner(imp.Banner) - if err != nil { - return openrtb2.Imp{}, &errortypes.BadInput{ - Message: fmt.Sprintf("imp #%s: %s", imp.ID, err.Error()), - } - } - imp.Banner = banner - } - return imp, nil -} - -func updateBanner(banner *openrtb2.Banner) (*openrtb2.Banner, error) { - bannerCopy := *banner - if bannerCopy.W == nil || bannerCopy.H == nil || *bannerCopy.W == 0 || *bannerCopy.H == 0 { - if len(bannerCopy.Format) > 0 { - w := bannerCopy.Format[0].W - h := bannerCopy.Format[0].H - bannerCopy.W = &w - bannerCopy.H = &h - } else { - return nil, fmt.Errorf("Invalid sizes provided for Banner") - } - } - return &bannerCopy, nil -} - -func (a *adapter) modifyUrl(extImp openrtb_ext.ExtImpIntertech, referer, cur string) string { - pageStr := strconv.Itoa(extImp.PageID) - impStr := strconv.Itoa(extImp.ImpID) - - resolvedUrl := strings.ReplaceAll(a.endpoint, pageIDMacro, url.QueryEscape(pageStr)) - resolvedUrl = strings.ReplaceAll(resolvedUrl, impIDMacro, url.QueryEscape(impStr)) - - if referer != "" { - resolvedUrl += "&target-ref=" + url.QueryEscape(referer) - } - - if cur != "" { - resolvedUrl += "&ssp-cur=" + cur - } - - return resolvedUrl -} - -func buildRequestData(bidRequest openrtb2.BidRequest, uri string) (*adapters.RequestData, error) { - body, err := jsonutil.Marshal(bidRequest) - if err != nil { - return nil, err - } - - headers := http.Header{} - headers.Add("Content-Type", "application/json;charset=utf-8") - headers.Add("Accept", "application/json") - - if bidRequest.Device != nil { - if bidRequest.Device.UA != "" { - headers.Add("User-Agent", bidRequest.Device.UA) - } - if bidRequest.Device.IP != "" { - headers.Add("X-Forwarded-For", bidRequest.Device.IP) - headers.Add("X-Real-Ip", bidRequest.Device.IP) - } - if bidRequest.Device.Language != "" { - headers.Add("Accept-Language", bidRequest.Device.Language) - } - } - return &adapters.RequestData{ - Method: http.MethodPost, - Uri: uri, - Body: body, - Headers: headers, - ImpIDs: openrtb_ext.GetImpIDs(bidRequest.Imp), - }, nil -} - -func getReferer(request *openrtb2.BidRequest) string { - if request.Site != nil { - return request.Site.Page - } - return "" -} - -func getCur(request *openrtb2.BidRequest) string { - if len(request.Cur) > 0 { - return request.Cur[0] - } - return "" -} - -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) { - switch bid.MType { - case openrtb2.MarkupBanner: - return openrtb_ext.BidTypeBanner, 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/intertech/intertech_test.go b/adapters/intertech/intertech_test.go deleted file mode 100644 index 952b2a4431..0000000000 --- a/adapters/intertech/intertech_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package intertech - -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.BidderIntertech, config.Adapter{ - Endpoint: "https://test.intertech.com/ssp?pid={{page_id}}&imp={{imp_id}}"}, config.Server{ - ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "intertechtest", bidder) -} diff --git a/adapters/intertech/intertechtest/exemplary/simple-banner-muli-format.json b/adapters/intertech/intertechtest/exemplary/simple-banner-muli-format.json deleted file mode 100644 index 39f1262628..0000000000 --- a/adapters/intertech/intertechtest/exemplary/simple-banner-muli-format.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "mockBidRequest": { - "id": "request-id-1", - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (X11; Linux x86_64)" - }, - "site": { - "page": "http://bannercheck.com" - }, - "imp": [ - { - "id": "imp-id-1", - "tagid": "tag-id-1", - "banner": { - "format": [ - { "w": 728, "h": 90 }, - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 1111, - "imp_id": 2222 - } - } - } - ], - "cur": ["USD"] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://test.intertech.com/ssp?pid=1111&imp=2222&target-ref=http%3A%2F%2Fbannercheck.com&ssp-cur=USD", - "body": { - "id": "request-id-1", - "imp": [ - { - "id": "imp-id-1", - "tagid": "tag-id-1", - "banner": { - "w": 728, - "h": 90, - "format": [ - { "w": 728, "h": 90 }, - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 1111, - "imp_id": 2222 - } - } - } - ], - "site": { - "page": "http://bannercheck.com" - }, - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (X11; Linux x86_64)" - }, - "cur": ["USD"] - }, - "impIDs": ["imp-id-1"] - }, - "mockResponse": { - "status": 200, - "body": { - "id": "request-id-1", - "cur": "USD", - "seatbid": [ - { - "seat": "intertech", - "bid": [ - { - "id": "bid-id-1", - "impid": "imp-id-1", - "price": 0.7, - "adm": "

Test Banner 728x90

", - "cid": "campaign-id-1", - "crid": "creative-id-1", - "w": 728, - "h": 90, - "mtype": 1 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "bids": [ - { - "bid": { - "id": "bid-id-1", - "impid": "imp-id-1", - "price": 0.7, - "adm": "

Test Banner 728x90

", - "cid": "campaign-id-1", - "crid": "creative-id-1", - "w": 728, - "h": 90, - "mtype": 1 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/intertech/intertechtest/exemplary/simple-banner.json b/adapters/intertech/intertechtest/exemplary/simple-banner.json deleted file mode 100644 index dc0473465a..0000000000 --- a/adapters/intertech/intertechtest/exemplary/simple-banner.json +++ /dev/null @@ -1,119 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (iPad; CPU OS 10_3 like Mac OS X)", - "language": "en-US" - }, - "site": { - "page": "mypage" - }, - "imp": [ - { - "id": "test-imp-id", - "tagid": "test-tag", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "page_id": 1001, - "imp_id": 2002 - } - } - } - ], - "cur": ["USD"] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://test.intertech.com/ssp?pid=1001&imp=2002&target-ref=mypage&ssp-cur=USD", - "headers": { - "Content-Type": ["application/json;charset=utf-8"], - "Accept": ["application/json"], - "Accept-Language": ["en-US"], - "User-Agent": ["Mozilla/5.0 (iPad; CPU OS 10_3 like Mac OS X)"], - "X-Forwarded-For": ["123.123.123.123"], - "X-Real-Ip": ["123.123.123.123"] - }, - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "tagid": "test-tag", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "page_id": 1001, - "imp_id": 2002 - } - } - } - ], - "site": { - "page": "mypage" - }, - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (iPad; CPU OS 10_3 like Mac OS X)", - "language": "en-US" - }, - "cur": ["USD"] - }, - "impIDs": ["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "cur": "USD", - "seatbid": [ - { - "seat": "intertech", - "bid": [ - { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.5, - "adm": "

Test Ad

", - "cid": "test_cid", - "crid": "test_crid", - "w": 300, - "h": 250, - "mtype": 1 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "bids": [ - { - "bid": { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.5, - "adm": "

Test Ad

", - "cid": "test_cid", - "crid": "test_crid", - "w": 300, - "h": 250, - "mtype": 1 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/intertech/intertechtest/exemplary/simple-native.json b/adapters/intertech/intertechtest/exemplary/simple-native.json deleted file mode 100644 index a9336b8ffb..0000000000 --- a/adapters/intertech/intertechtest/exemplary/simple-native.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-native-request-id", - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X)" - }, - "site": { - "page": "nativepage" - }, - "imp": [ - { - "id": "test-native-imp-id", - "tagid": "test-native-tag", - "native": { - "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":25}}],\"eventtrackers\":[{\"event\":1,\"method\":1}],\"ver\":\"1.2\"}" - }, - "ext": { - "bidder": { - "page_id": 3003, - "imp_id": 4004 - } - } - } - ], - "cur": ["USD"] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://test.intertech.com/ssp?pid=3003&imp=4004&target-ref=nativepage&ssp-cur=USD", - "body": { - "id": "test-native-request-id", - "imp": [ - { - "id": "test-native-imp-id", - "tagid": "test-native-tag", - "native": { - "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":25}}],\"eventtrackers\":[{\"event\":1,\"method\":1}],\"ver\":\"1.2\"}" - }, - "ext": { - "bidder": { - "page_id": 3003, - "imp_id": 4004 - } - } - } - ], - "site": { - "page": "nativepage" - }, - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X)" - }, - "cur": ["USD"] - }, - "impIDs": ["test-native-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-native-request-id", - "cur": "USD", - "seatbid": [ - { - "seat": "intertech", - "bid": [ - { - "id": "test_native_bid_id", - "impid": "test-native-imp-id", - "price": 1.0, - "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Native Title\"}}],\"link\":{\"url\":\"http://example.com\"},\"imptrackers\":[\"http://example.com/imp\"]}}", - "cid": "test_native_cid", - "crid": "test_native_crid", - "mtype": 4 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "bids": [ - { - "bid": { - "id": "test_native_bid_id", - "impid": "test-native-imp-id", - "price": 1.0, - "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Native Title\"}}],\"link\":{\"url\":\"http://example.com\"},\"imptrackers\":[\"http://example.com/imp\"]}}", - "cid": "test_native_cid", - "crid": "test_native_crid", - "mtype": 4 - }, - "type": "native" - } - ] - } - ] -} \ No newline at end of file diff --git a/adapters/intertech/intertechtest/supplemental/bad_media_type.json b/adapters/intertech/intertechtest/supplemental/bad_media_type.json deleted file mode 100644 index 4e1074f136..0000000000 --- a/adapters/intertech/intertechtest/supplemental/bad_media_type.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" - }, - "site": { - "page": "http://example.com" - }, - "imp": [ - { - "id": "test-imp-id", - "tagid": "test-tag", - "banner": { - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 3003, - "imp_id": 5005 - } - } - } - ], - "cur": ["USD"] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://test.intertech.com/ssp?pid=3003&imp=5005&target-ref=http%3A%2F%2Fexample.com&ssp-cur=USD", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "tagid": "test-tag", - "banner": { - "w": 300, - "h": 250, - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 3003, - "imp_id": 5005 - } - } - } - ], - "site": { - "page": "http://example.com" - }, - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" - }, - "cur": ["USD"] - }, - "impIDs": ["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "cur": "USD", - "seatbid": [ - { - "seat": "intertech", - "bid": [ - { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.5, - "adm": "

Test Ad

", - "cid": "test_cid", - "crid": "test_crid", - "w": 300, - "h": 250, - "mtype": 2 - } - ] - } - ] - } - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "could not define media type for impression: test-imp-id", - "comparison": "literal" - } - ] - } - \ No newline at end of file diff --git a/adapters/intertech/intertechtest/supplemental/bad_response.json b/adapters/intertech/intertechtest/supplemental/bad_response.json deleted file mode 100644 index 6ca58d71dd..0000000000 --- a/adapters/intertech/intertechtest/supplemental/bad_response.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" - }, - "site": { - "page": "http://example.com" - }, - "imp": [ - { - "id": "test-imp-id", - "tagid": "test-tag", - "banner": { - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 1001, - "imp_id": 2002 - } - } - } - ], - "cur": ["USD"] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://test.intertech.com/ssp?pid=1001&imp=2002&target-ref=http%3A%2F%2Fexample.com&ssp-cur=USD", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "tagid": "test-tag", - "banner": { - "w": 300, - "h": 250, - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 1001, - "imp_id": 2002 - } - } - } - ], - "site": { - "page": "http://example.com" - }, - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" - }, - "cur": ["USD"] - }, - "impIDs": ["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": "" - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "expect { or n, but found \"", - "comparison": "literal" - } - ] - } - \ No newline at end of file diff --git a/adapters/intertech/intertechtest/supplemental/invalid-banner-size.json b/adapters/intertech/intertechtest/supplemental/invalid-banner-size.json deleted file mode 100644 index 49d6a4996c..0000000000 --- a/adapters/intertech/intertechtest/supplemental/invalid-banner-size.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-invalid-sizes-request-id", - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (X11; Linux x86_64)" - }, - "site": { - "page": "http://no-size-banner.com" - }, - "imp": [ - { - "id": "test-imp-no-size", - "tagid": "no-size-tag", - "banner": { - "format": [] - }, - "ext": { - "bidder": { - "page_id": 1111, - "imp_id": 9999 - } - } - } - ], - "cur": ["USD"] - }, - "httpCalls": [], - "expectedMakeRequestsErrors": [ - { - "value": "imp #test-imp-no-size: Invalid sizes provided for Banner", - "comparison": "literal" - } - ] -} diff --git a/adapters/intertech/intertechtest/supplemental/no-cur-req.json b/adapters/intertech/intertechtest/supplemental/no-cur-req.json deleted file mode 100644 index a6101b6023..0000000000 --- a/adapters/intertech/intertechtest/supplemental/no-cur-req.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-no-cur-request-id", - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (X11; Linux x86_64)" - }, - "site": { - "page": "http://example-nocur.com" - }, - "imp": [ - { - "id": "test-imp-no-cur", - "tagid": "no-cur-tag", - "banner": { - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 1111, - "imp_id": 2222 - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://test.intertech.com/ssp?pid=1111&imp=2222&target-ref=http%3A%2F%2Fexample-nocur.com", - "body": { - "id": "test-no-cur-request-id", - "imp": [ - { - "id": "test-imp-no-cur", - "tagid": "no-cur-tag", - "banner": { - "w": 300, - "h": 250, - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 1111, - "imp_id": 2222 - } - } - } - ], - "site": { - "page": "http://example-nocur.com" - }, - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (X11; Linux x86_64)" - } - }, - "impIDs": ["test-imp-no-cur"] - }, - "mockResponse": { - "status": 204, - "body": {} - } - } - ], - "expectedBidResponses": [] -} diff --git a/adapters/intertech/intertechtest/supplemental/no-site-req.json b/adapters/intertech/intertechtest/supplemental/no-site-req.json deleted file mode 100644 index 9d4901994b..0000000000 --- a/adapters/intertech/intertechtest/supplemental/no-site-req.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-no-site-request-id", - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (X11; Linux x86_64)" - }, - "imp": [ - { - "id": "test-imp-no-site", - "tagid": "no-site-tag", - "banner": { - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 3003, - "imp_id": 5005 - } - } - } - ], - "cur": ["USD"] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://test.intertech.com/ssp?pid=3003&imp=5005&ssp-cur=USD", - "body": { - "id": "test-no-site-request-id", - "imp": [ - { - "id": "test-imp-no-site", - "tagid": "no-site-tag", - "banner": { - "w": 300, - "h": 250, - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 3003, - "imp_id": 5005 - } - } - } - ], - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (X11; Linux x86_64)" - }, - "cur": ["USD"] - }, - "impIDs": ["test-imp-no-site"] - }, - "mockResponse": { - "status": 204, - "body": {} - } - } - ], - "expectedBidResponses": [] -} diff --git a/adapters/intertech/intertechtest/supplemental/status-204.json b/adapters/intertech/intertechtest/supplemental/status-204.json deleted file mode 100644 index 8225c9ea57..0000000000 --- a/adapters/intertech/intertechtest/supplemental/status-204.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" - }, - "site": { - "page": "http://example.com" - }, - "imp": [ - { - "id": "test-imp-id", - "tagid": "test-tag", - "banner": { - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 1001, - "imp_id": 2002 - } - } - } - ], - "cur": ["USD"] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://test.intertech.com/ssp?pid=1001&imp=2002&target-ref=http%3A%2F%2Fexample.com&ssp-cur=USD", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "tagid": "test-tag", - "banner": { - "w": 300, - "h": 250, - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 1001, - "imp_id": 2002 - } - } - } - ], - "site": { - "page": "http://example.com" - }, - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" - }, - "cur": ["USD"] - }, - "impIDs": ["test-imp-id"] - }, - "mockResponse": { - "status": 204, - "body": {} - } - } - ], - "expectedBidResponses": [] -} diff --git a/adapters/intertech/intertechtest/supplemental/status-not-200.json b/adapters/intertech/intertechtest/supplemental/status-not-200.json deleted file mode 100644 index 58317e359f..0000000000 --- a/adapters/intertech/intertechtest/supplemental/status-not-200.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" - }, - "site": { - "page": "http://mypage.com" - }, - "imp": [ - { - "id": "test-imp-id", - "tagid": "test-tag", - "banner": { - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 1001, - "imp_id": 2002 - } - } - } - ], - "cur": ["USD"] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://test.intertech.com/ssp?pid=1001&imp=2002&target-ref=http%3A%2F%2Fmypage.com&ssp-cur=USD", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "tagid": "test-tag", - "banner": { - "w": 300, - "h": 250, - "format": [ - { "w": 300, "h": 250 } - ] - }, - "ext": { - "bidder": { - "page_id": 1001, - "imp_id": 2002 - } - } - } - ], - "site": { - "page": "http://mypage.com" - }, - "device": { - "ip": "123.123.123.123", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" - }, - "cur": ["USD"] - }, - "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/invibes/invibes.go b/adapters/invibes/invibes.go index 4657be2974..a157fddff8 100644 --- a/adapters/invibes/invibes.go +++ b/adapters/invibes/invibes.go @@ -10,13 +10,13 @@ import ( "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/metrics" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const adapterVersion = "prebid_1.0.0" diff --git a/adapters/invibes/invibes_test.go b/adapters/invibes/invibes_test.go index be8dda3ffd..1c27e09edb 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/invibes/params_test.go b/adapters/invibes/params_test.go index 48be52c4ba..2a5394488b 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/iqx/iqx.go b/adapters/iqx/iqx.go index c3519b10b1..ea2100ef0d 100644 --- a/adapters/iqx/iqx.go +++ b/adapters/iqx/iqx.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type bidType struct { diff --git a/adapters/iqx/iqxtest_test.go b/adapters/iqx/iqxtest_test.go index 190560d6de..6504c0e1d4 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/iqx/params_test.go b/adapters/iqx/params_test.go index 4b687728b2..883bb46a37 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/iqzone/iqzone.go b/adapters/iqzone/iqzone.go index 9becbfbb89..2aaf90eeb7 100644 --- a/adapters/iqzone/iqzone.go +++ b/adapters/iqzone/iqzone.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/iqzone/iqzone_test.go b/adapters/iqzone/iqzone_test.go index 37ba833f50..bda00b1527 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/iqzone/params_test.go b/adapters/iqzone/params_test.go index 4d3aa165a6..f1b6ba1c4d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/ix/ix.go b/adapters/ix/ix.go index c4853f8aae..c5624dd96e 100644 --- a/adapters/ix/ix.go +++ b/adapters/ix/ix.go @@ -7,13 +7,13 @@ import ( "sort" "strings" - "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/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" + "github.com/prebid/prebid-server/v4/version" "github.com/prebid/openrtb/v20/native1" native1response "github.com/prebid/openrtb/v20/native1/response" diff --git a/adapters/ix/ix_test.go b/adapters/ix/ix_test.go index d46b69adff..eb6b96f42a 100644 --- a/adapters/ix/ix_test.go +++ b/adapters/ix/ix_test.go @@ -4,11 +4,11 @@ import ( "encoding/json" "testing" - "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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/prebid/openrtb/v20/adcom1" diff --git a/adapters/ix/params_test.go b/adapters/ix/params_test.go index 90d591b50c..e1f4b44663 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/jixie/jixie.go b/adapters/jixie/jixie.go index d0411d1e5e..9ab479664f 100644 --- a/adapters/jixie/jixie.go +++ b/adapters/jixie/jixie.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/jixie/jixie_test.go b/adapters/jixie/jixie_test.go index 6fe4fa24ce..cf217eb4f0 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/jixie/params_test.go b/adapters/jixie/params_test.go index 653f3f86e1..1cd650a94d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/kargo/kargo.go b/adapters/kargo/kargo.go index da12ef68ca..c75b681280 100644 --- a/adapters/kargo/kargo.go +++ b/adapters/kargo/kargo.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/kargo/kargo_test.go b/adapters/kargo/kargo_test.go index 0e7eb83bc1..fe3ba8bab5 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/kargo/params_test.go b/adapters/kargo/params_test.go index 91b46fbc4e..2bd805d0a3 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/kayzen/kayzen.go b/adapters/kayzen/kayzen.go index 680362603e..d5835a38e6 100644 --- a/adapters/kayzen/kayzen.go +++ b/adapters/kayzen/kayzen.go @@ -7,12 +7,13 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/urlutil" ) type adapter struct { @@ -92,6 +93,9 @@ func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtKayzen, e } func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtKayzen) (string, error) { + if !urlutil.IsSafeHost(params.Zone) { + return "", &errortypes.BadInput{Message: "Invalid Zone"} + } endpointParams := macros.EndpointTemplateParams{ ZoneID: params.Zone, AccountID: params.Exchange, diff --git a/adapters/kayzen/kayzen_test.go b/adapters/kayzen/kayzen_test.go index 6b3776ddba..3b0644906e 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/kayzen/kayzentest/supplemental/invalid-zone.json b/adapters/kayzen/kayzentest/supplemental/invalid-zone.json new file mode 100644 index 0000000000..fb22602ffa --- /dev/null +++ b/adapters/kayzen/kayzentest/supplemental/invalid-zone.json @@ -0,0 +1,28 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "zone": "evil.com/path?redirect=http://attacker.com#", + "exchange": "ex" + } + } + } + ], + "site": { + "page": "test.com" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Invalid Zone", + "comparison": "literal" + } + ] +} diff --git a/adapters/kayzen/params_test.go b/adapters/kayzen/params_test.go index 647f77d134..45f07b9eed 100644 --- a/adapters/kayzen/params_test.go +++ b/adapters/kayzen/params_test.go @@ -4,11 +4,16 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ `{ "zone": "dc", "exchange": "ex" }`, + `{ "zone": "host", "exchange": "ex" }`, + `{ "zone": "host.example.com", "exchange": "ex" }`, + `{ "zone": "host-example.test", "exchange": "ex" }`, + `{ "zone": "Host.Example.com", "exchange": "ex" }`, + `{ "zone": "localhost", "exchange": "ex" }`, } func TestValidParams(t *testing.T) { @@ -39,6 +44,16 @@ var invalidParams = []string{ `{ "exchange": "", "zone" : "" }`, `{ "exchange": "ex", "zone" : "" }`, `{ "exchange": "", "zone" : "dc" }`, + `{ "zone": "/path", "exchange": "ex" }`, + `{ "zone": "//evil.com", "exchange": "ex" }`, + `{ "zone": "host/path", "exchange": "ex" }`, + `{ "zone": "host?query=1", "exchange": "ex" }`, + `{ "zone": "host#fragment", "exchange": "ex" }`, + `{ "zone": "user@host", "exchange": "ex" }`, + `{ "zone": "https://host.com", "exchange": "ex" }`, + `{ "zone": "host:notaport", "exchange": "ex" }`, + `{ "zone": "host:8080:extra", "exchange": "ex" }`, + `{ "zone": "host:8080", "exchange": "ex" }`, } func TestInvalidParams(t *testing.T) { diff --git a/adapters/kidoz/kidoz.go b/adapters/kidoz/kidoz.go index 88628085ef..df9d1fe457 100644 --- a/adapters/kidoz/kidoz.go +++ b/adapters/kidoz/kidoz.go @@ -7,11 +7,11 @@ import ( "strconv" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type KidozAdapter struct { diff --git a/adapters/kidoz/kidoz_test.go b/adapters/kidoz/kidoz_test.go index 8923518559..59b1b63f22 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/kidoz/params_test.go b/adapters/kidoz/params_test.go index 1dfa3e8955..87521a27fd 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/kiviads/kiviads.go b/adapters/kiviads/kiviads.go index ad5dcb58e2..98ab0dc0ca 100644 --- a/adapters/kiviads/kiviads.go +++ b/adapters/kiviads/kiviads.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/kiviads/kiviads_test.go b/adapters/kiviads/kiviads_test.go index dd83e0d177..c754fea012 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/kiviads/params_test.go b/adapters/kiviads/params_test.go index 0192795006..12a46ce732 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/kobler/kobler.go b/adapters/kobler/kobler.go index cb1a1acaa7..30c88ba55f 100644 --- a/adapters/kobler/kobler.go +++ b/adapters/kobler/kobler.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/kobler/kobler_test.go b/adapters/kobler/kobler_test.go index 0cd924b8ba..622a43c8dc 100644 --- a/adapters/kobler/kobler_test.go +++ b/adapters/kobler/kobler_test.go @@ -3,9 +3,9 @@ package kobler 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/kobler/params_test.go b/adapters/kobler/params_test.go index bc8b3ec9bf..d40dbfba14 100644 --- a/adapters/kobler/params_test.go +++ b/adapters/kobler/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/krushmedia/krushmedia.go b/adapters/krushmedia/krushmedia.go index fd2a0adf8b..3d95cd94fb 100644 --- a/adapters/krushmedia/krushmedia.go +++ b/adapters/krushmedia/krushmedia.go @@ -8,12 +8,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type KrushmediaAdapter struct { diff --git a/adapters/krushmedia/krushmedia_test.go b/adapters/krushmedia/krushmedia_test.go index 26117ce103..f39f62993b 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/krushmedia/params_test.go b/adapters/krushmedia/params_test.go index babf6b205d..0fc1a0fbb7 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/kueezrtb/kueezrtb.go b/adapters/kueezrtb/kueezrtb.go index 0edfbffd38..cd2000747d 100644 --- a/adapters/kueezrtb/kueezrtb.go +++ b/adapters/kueezrtb/kueezrtb.go @@ -4,11 +4,11 @@ import ( "encoding/json" "fmt" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "net/http" "net/url" ) diff --git a/adapters/kueezrtb/kueezrtb_test.go b/adapters/kueezrtb/kueezrtb_test.go index b62eff292d..82b233a6fa 100644 --- a/adapters/kueezrtb/kueezrtb_test.go +++ b/adapters/kueezrtb/kueezrtb_test.go @@ -3,9 +3,9 @@ package kueezrtb 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/kueezrtb/params_test.go b/adapters/kueezrtb/params_test.go index 33e5ea0a64..4fdf113bd7 100644 --- a/adapters/kueezrtb/params_test.go +++ b/adapters/kueezrtb/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/lemmadigital/lemmadigital.go b/adapters/lemmadigital/lemmadigital.go index 16d93d47be..a098699dc8 100644 --- a/adapters/lemmadigital/lemmadigital.go +++ b/adapters/lemmadigital/lemmadigital.go @@ -8,12 +8,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/lemmadigital/lemmadigital_test.go b/adapters/lemmadigital/lemmadigital_test.go index d3e770bb63..a6705f391f 100644 --- a/adapters/lemmadigital/lemmadigital_test.go +++ b/adapters/lemmadigital/lemmadigital_test.go @@ -3,9 +3,9 @@ package lemmadigital 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/lemmadigital/params_test.go b/adapters/lemmadigital/params_test.go index c8c739ff59..b9335a1efa 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // Tests for static/bidder-params/lemmadigital.json diff --git a/adapters/limelightDigital/limelightDigital.go b/adapters/limelightDigital/limelightDigital.go index 18ba5dd6f7..47566812cc 100644 --- a/adapters/limelightDigital/limelightDigital.go +++ b/adapters/limelightDigital/limelightDigital.go @@ -10,12 +10,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/limelightDigital/limelightDigital_test.go b/adapters/limelightDigital/limelightDigital_test.go index 2b36ee573d..1f838245cb 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/limelightDigital/params_test.go b/adapters/limelightDigital/params_test.go index 04c49d8373..a4aaa4466c 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/lm_kiviads/lmkiviads.go b/adapters/lm_kiviads/lmkiviads.go index bc4e48b1d7..e94a9a9aba 100644 --- a/adapters/lm_kiviads/lmkiviads.go +++ b/adapters/lm_kiviads/lmkiviads.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type bidType struct { diff --git a/adapters/lm_kiviads/lmkiviads_test.go b/adapters/lm_kiviads/lmkiviads_test.go index 34ea2bf467..05d8458250 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/lm_kiviads/params_test.go b/adapters/lm_kiviads/params_test.go index 00f76bca95..2d77754e06 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/lockerdome/lockerdome.go b/adapters/lockerdome/lockerdome.go index 2206b82015..ac79a67262 100644 --- a/adapters/lockerdome/lockerdome.go +++ b/adapters/lockerdome/lockerdome.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const unexpectedStatusCodeMessage = "Unexpected status code: %d. Run with request.debug = 1 for more info" diff --git a/adapters/lockerdome/lockerdome_test.go b/adapters/lockerdome/lockerdome_test.go index b0c12083e4..3d2de082dd 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/lockerdome/params_test.go b/adapters/lockerdome/params_test.go index 50504b68d2..3a15f24855 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file tests static/bidder-params/lockerdome.json diff --git a/adapters/logan/logan.go b/adapters/logan/logan.go index a5f995108f..bff7cbcbec 100644 --- a/adapters/logan/logan.go +++ b/adapters/logan/logan.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/logan/logan_test.go b/adapters/logan/logan_test.go index 8e677c5585..a465282d71 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/logan/params_test.go b/adapters/logan/params_test.go index 76c8cb3dd8..c09b6c4f83 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/logicad/logicad.go b/adapters/logicad/logicad.go index a1dc40fdcf..8f81e4a7cd 100644 --- a/adapters/logicad/logicad.go +++ b/adapters/logicad/logicad.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type LogicadAdapter struct { diff --git a/adapters/logicad/logicad_test.go b/adapters/logicad/logicad_test.go index a15d381cbb..c58f39085c 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/logicad/params_test.go b/adapters/logicad/params_test.go index 06f15d9d1b..9a15906c8f 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/loopme/loopme.go b/adapters/loopme/loopme.go index d4b9d7906f..fde97aee06 100644 --- a/adapters/loopme/loopme.go +++ b/adapters/loopme/loopme.go @@ -6,10 +6,10 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type adapter struct { diff --git a/adapters/loopme/loopme_test.go b/adapters/loopme/loopme_test.go index ca293c45ce..003a240c27 100644 --- a/adapters/loopme/loopme_test.go +++ b/adapters/loopme/loopme_test.go @@ -3,9 +3,9 @@ package loopme 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/loopme/params_test.go b/adapters/loopme/params_test.go index 12ddf8e985..9ff1acf3d4 100644 --- a/adapters/loopme/params_test.go +++ b/adapters/loopme/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/loopme.json diff --git a/adapters/loyal/loyal.go b/adapters/loyal/loyal.go index efe069c638..8a16c4f5bd 100644 --- a/adapters/loyal/loyal.go +++ b/adapters/loyal/loyal.go @@ -7,10 +7,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/loyal/loyal_test.go b/adapters/loyal/loyal_test.go index 1836b267be..5664860199 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/loyal/params_test.go b/adapters/loyal/params_test.go index e0c47d5030..ae1ba114ee 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/lunamedia/lunamedia.go b/adapters/lunamedia/lunamedia.go index 3db1b12ad4..2c5b87aa6c 100644 --- a/adapters/lunamedia/lunamedia.go +++ b/adapters/lunamedia/lunamedia.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type LunaMediaAdapter struct { diff --git a/adapters/lunamedia/lunamedia_test.go b/adapters/lunamedia/lunamedia_test.go index 8677fbb297..b04789370a 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/lunamedia/params_test.go b/adapters/lunamedia/params_test.go index b78b94934d..6ff7240b5d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/mabidder/mabidder.go b/adapters/mabidder/mabidder.go index 25d2830ef9..99a37ce8bd 100644 --- a/adapters/mabidder/mabidder.go +++ b/adapters/mabidder/mabidder.go @@ -4,10 +4,10 @@ import ( "encoding/json" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type serverResponse struct { diff --git a/adapters/mabidder/mabidder_test.go b/adapters/mabidder/mabidder_test.go index f821752e9b..8aa74d5b03 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mabidder/params_test.go b/adapters/mabidder/params_test.go index bd4162448f..1d216b4d42 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/madsense/madsense.go b/adapters/madsense/madsense.go index 5cf32d64d5..d827fcb36c 100644 --- a/adapters/madsense/madsense.go +++ b/adapters/madsense/madsense.go @@ -5,11 +5,11 @@ import ( "net/url" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/madsense/madsense_test.go b/adapters/madsense/madsense_test.go index 8093066ac5..f1f6c1f3a4 100644 --- a/adapters/madsense/madsense_test.go +++ b/adapters/madsense/madsense_test.go @@ -1,9 +1,9 @@ package madsense import ( - "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/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/require" "testing" ) diff --git a/adapters/madsense/params_test.go b/adapters/madsense/params_test.go index de59706745..32283395ad 100644 --- a/adapters/madsense/params_test.go +++ b/adapters/madsense/params_test.go @@ -2,7 +2,7 @@ package madsense import ( "encoding/json" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/require" "testing" ) diff --git a/adapters/madsense/utils.go b/adapters/madsense/utils.go index 992d136330..fb1d168d6f 100644 --- a/adapters/madsense/utils.go +++ b/adapters/madsense/utils.go @@ -5,10 +5,10 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/adapters" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) func parseImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpMadSense, error) { diff --git a/adapters/madvertise/madvertise.go b/adapters/madvertise/madvertise.go index d8c6fc3953..bcc95ed889 100644 --- a/adapters/madvertise/madvertise.go +++ b/adapters/madvertise/madvertise.go @@ -8,12 +8,12 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/madvertise/madvertise_test.go b/adapters/madvertise/madvertise_test.go index e402ae4dc7..edfb3f3356 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/madvertise/params_test.go b/adapters/madvertise/params_test.go index c155d5beda..f5f1af383f 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 92bfa0dc9f..b9548e77f9 100644 --- a/adapters/marsmedia/marsmedia.go +++ b/adapters/marsmedia/marsmedia.go @@ -7,11 +7,11 @@ import ( "strconv" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type MarsmediaAdapter struct { diff --git a/adapters/marsmedia/marsmedia_test.go b/adapters/marsmedia/marsmedia_test.go index 4164d433fd..5b3da23b36 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/marsmedia/params_test.go b/adapters/marsmedia/params_test.go index 7961d21455..e2c00c9683 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 index dc7ee01b9f..428e6cb15f 100644 --- a/adapters/mediago/mediago.go +++ b/adapters/mediago/mediago.go @@ -9,12 +9,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/mediago/mediago_test.go b/adapters/mediago/mediago_test.go index d6a480c828..944643e417 100644 --- a/adapters/mediago/mediago_test.go +++ b/adapters/mediago/mediago_test.go @@ -5,9 +5,9 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mediago/params_test.go b/adapters/mediago/params_test.go index c1a7fbd3e4..9639863066 100644 --- a/adapters/mediago/params_test.go +++ b/adapters/mediago/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/medianet/medianet.go b/adapters/medianet/medianet.go index 08a1ae021f..06ae131f69 100644 --- a/adapters/medianet/medianet.go +++ b/adapters/medianet/medianet.go @@ -7,11 +7,11 @@ import ( "net/url" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/medianet/medianet_test.go b/adapters/medianet/medianet_test.go index 8721c6984c..84efea60bc 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/medianet/params_test.go b/adapters/medianet/params_test.go index 15cd4acbab..78c520a8f1 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/medianet.json diff --git a/adapters/mediasquare/mediasquare.go b/adapters/mediasquare/mediasquare.go index c23164c254..8b232b44a8 100644 --- a/adapters/mediasquare/mediasquare.go +++ b/adapters/mediasquare/mediasquare.go @@ -5,11 +5,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { @@ -33,7 +33,6 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E } msqParams := initMsqParams(request) - msqParams.Test = (request.Test == int8(1)) for _, imp := range request.Imp { var ( bidderExt adapters.ExtImpBidder @@ -88,7 +87,6 @@ func (a *adapter) makeRequest(request *openrtb2.BidRequest, msqParams *msqParame } else { err = errorWriter(" jsonutil.Marshal", err, false) } - return } diff --git a/adapters/mediasquare/mediasquare_test.go b/adapters/mediasquare/mediasquare_test.go index 091f13ba19..25df6fb351 100644 --- a/adapters/mediasquare/mediasquare_test.go +++ b/adapters/mediasquare/mediasquare_test.go @@ -4,10 +4,10 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/mediasquare/mediasquaretest/exemplary/multi-format.json b/adapters/mediasquare/mediasquaretest/exemplary/multi-format.json index 335da6ab6c..ba89936eaf 100644 --- a/adapters/mediasquare/mediasquaretest/exemplary/multi-format.json +++ b/adapters/mediasquare/mediasquaretest/exemplary/multi-format.json @@ -126,14 +126,21 @@ "language": "fr", "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" }, + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, "regs": { "gdpr": 1, "ext": { - "dsa": "mediasquare-test" + "dsa": { + "msq_test": 42 + } } }, "user": { - "consent": "there-is-a-real-cs-in-it" + "consent": "there-is-a-real-cs-in-it", + "buyeruid": "42" }, "test": 1 }, @@ -237,7 +244,10 @@ "consent_required": true, "consent_string": "there-is-a-real-cs-in-it" }, - "dsa": "mediasquare-test", + "dsa": { + "msq_test": 42 + }, + "pbjs": "prebid-test-version", "tech": { "device": { "geo": { @@ -257,10 +267,19 @@ "id": "MEDIA_SQUARE" }, "content": {} + }, + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "user": { + "consent": "there-is-a-real-cs-in-it", + "buyeruid": "42" } }, "type": "pbs", - "test": true + "test": true, + "user_uid": "42" }, "impIDs": [ "2c35e25e-e7d3-41bf-b810-06a449f456b9", @@ -293,7 +312,12 @@ "transaction_id": "2c35e25e-e7d3-41bf-b810-06a449f456b9", "ttl": 20000, "adomain": ["mediasquare.fr"], - "hasConsent": true + "hasConsent": true, + "dsa": { + "adrender": 1, + "behalf": "test-behalf", + "paid": "test-paid" + } }, { "ad": "\u003c!-- This is an example --\u003e", @@ -309,7 +333,12 @@ "transaction_id": "2059a3e6-71a3-43ea-8290-b5ceb13d35a8", "ttl": 20000, "adomain": ["mediasquare.fr"], - "hasConsent": true + "hasConsent": true, + "dsa": { + "adrender": 1, + "behalf": "test-behalf", + "paid": "test-paid" + } }, { "bid_id": "2c35e25e-e7d3-41bf-b810-06a449f456c9", @@ -327,7 +356,12 @@ "title": "Learn about this awesome thing" }, "adomain": ["mediasquare.fr"], - "hasConsent": true + "hasConsent": true, + "dsa": { + "adrender": 1, + "behalf": "test-behalf", + "paid": "test-paid" + } }, { "bid_id": "2c35e25e-e7d3-41bf-b810-06a449f456d9", @@ -345,27 +379,14 @@ "url": "https://dummy.domain.tv/some_vast" }, "adomain": ["mediasquare.fr"], - "hasConsent": true - } - ], - "Calc_cpm": { - "2059a3e6-71a3-43ea-8290-b5ceb13d35a8": { - "TmpCpmMax": 0, - "CpmMax": 0.02 - }, - "2c35e25e-e7d3-41bf-b810-06a449f456b9": { - "TmpCpmMax": 0, - "CpmMax": 2 - }, - "2c35e25e-e7d3-41bf-b810-06a449f456c9": { - "TmpCpmMax": 0, - "CpmMax": 2 - }, - "2c35e25e-e7d3-41bf-b810-06a449f456d9": { - "TmpCpmMax": 0, - "CpmMax": 2 + "hasConsent": true, + "dsa": { + "adrender": 1, + "behalf": "test-behalf", + "paid": "test-paid" + } } - } + ] } } } @@ -382,6 +403,13 @@ "adm": "\u003c!-- This is an example --\u003e", "adomain": ["mediasquare.fr"], "crid": "msq_test|fakeCreative", + "ext": { + "dsa": { + "adrender": 1, + "behalf": "test-behalf", + "paid": "test-paid" + } + }, "w": 250, "mtype": 1 }, @@ -399,6 +427,13 @@ "adm": "\u003c!-- This is an example --\u003e", "adomain": ["mediasquare.fr"], "crid": "msq_test|fakeCreative", + "ext": { + "dsa": { + "adrender": 1, + "behalf": "test-behalf", + "paid": "test-paid" + } + }, "w": 250, "mtype": 1 }, @@ -415,6 +450,13 @@ "price": 2, "adomain": ["mediasquare.fr"], "crid": "msq_test|fakeCreative", + "ext": { + "dsa": { + "adrender": 1, + "behalf": "test-behalf", + "paid": "test-paid" + } + }, "mtype": 4 }, "BidMeta": { @@ -430,6 +472,13 @@ "price": 2, "adomain": ["mediasquare.fr"], "crid": "msq_test|fakeCreative", + "ext": { + "dsa": { + "adrender": 1, + "behalf": "test-behalf", + "paid": "test-paid" + } + }, "mtype": 2 }, "BidMeta": { diff --git a/adapters/mediasquare/mediasquaretest/exemplary/simple-banner.json b/adapters/mediasquare/mediasquaretest/exemplary/simple-banner.json index 8769b37df1..5753abb611 100644 --- a/adapters/mediasquare/mediasquaretest/exemplary/simple-banner.json +++ b/adapters/mediasquare/mediasquaretest/exemplary/simple-banner.json @@ -58,7 +58,9 @@ "regs": { "gdpr": 1, "ext": { - "dsa": "mediasquare-test" + "dsa": { + "msq_test": 42 + } } }, "user": { @@ -126,7 +128,10 @@ "consent_required": true, "consent_string": "there-is-a-real-cs-in-it" }, - "dsa": "mediasquare-test", + "dsa": { + "msq_test": 42 + }, + "pbjs": "prebid-test-version", "tech": { "device": { "geo": { @@ -146,10 +151,14 @@ "id": "MEDIA_SQUARE" }, "content": {} + }, + "user": { + "consent": "there-is-a-real-cs-in-it" } }, "type": "pbs", - "test": true + "test": true, + "user_uid": "" }, "impIDs": [ "2c35e25e-e7d3-41bf-b810-06a449f456b9", diff --git a/adapters/mediasquare/mediasquaretest/exemplary/simple-native.json b/adapters/mediasquare/mediasquaretest/exemplary/simple-native.json index 9a9e842b34..23d29d544b 100644 --- a/adapters/mediasquare/mediasquaretest/exemplary/simple-native.json +++ b/adapters/mediasquare/mediasquaretest/exemplary/simple-native.json @@ -42,13 +42,16 @@ "regs": { "gdpr": 1, "ext": { - "dsa": "mediasquare-test" + "dsa": { + "msq_test": 42 + } } }, "user": { "consent": "there-is-a-real-cs-in-it" }, - "test": 1 + "test": 1, + "user_uid": "" }, "httpCalls": [ @@ -76,7 +79,10 @@ "consent_required": true }, "type": "pbs", - "dsa": "mediasquare-test", + "dsa": { + "msq_test": 42 + }, + "pbjs": "prebid-test-version", "tech": { "device": { "geo": { @@ -96,9 +102,13 @@ "id": "MEDIA_SQUARE" }, "content": {} + }, + "user": { + "consent": "there-is-a-real-cs-in-it" } }, - "test": true + "test": true, + "user_uid": "" }, "impIDs": ["2c35e25e-e7d3-41bf-b810-06a449f456b9"] }, diff --git a/adapters/mediasquare/mediasquaretest/exemplary/simple-video.json b/adapters/mediasquare/mediasquaretest/exemplary/simple-video.json index 13de7f873b..bd00984ad7 100644 --- a/adapters/mediasquare/mediasquaretest/exemplary/simple-video.json +++ b/adapters/mediasquare/mediasquaretest/exemplary/simple-video.json @@ -52,7 +52,9 @@ "regs": { "gdpr": 1, "ext": { - "dsa": "mediasquare-test" + "dsa": { + "msq_test": 42 + } } }, "user": { @@ -100,7 +102,10 @@ "consent_required": true }, "type": "pbs", - "dsa": "mediasquare-test", + "dsa": { + "msq_test": 42 + }, + "pbjs": "prebid-test-version", "tech": { "device": { "geo": { @@ -120,9 +125,13 @@ "id": "MEDIA_SQUARE" }, "content": {} + }, + "user": { + "consent": "there-is-a-real-cs-in-it" } }, - "test": true + "test": true, + "user_uid": "" }, "impIDs": ["2c35e25e-e7d3-41bf-b810-06a449f456b9"] }, diff --git a/adapters/mediasquare/mediasquaretest/supplemental/no-valid-imp-ext.json b/adapters/mediasquare/mediasquaretest/supplemental/no-valid-imp-ext.json index 6fae03fd4e..3c43f93784 100644 --- a/adapters/mediasquare/mediasquaretest/supplemental/no-valid-imp-ext.json +++ b/adapters/mediasquare/mediasquaretest/supplemental/no-valid-imp-ext.json @@ -51,9 +51,10 @@ "codes": null, "gdpr": { "consent_required": false, "consent_string": "" }, "type": "pbs", - "dsa": "", - "tech": { "device": null, "app": null }, - "test": true + "pbjs": "prebid-test-version", + "tech": {}, + "test": true, + "user_uid": "" }, "impIDs": ["0", "1", "-42", "-1", "-0", "42"] }, diff --git a/adapters/mediasquare/mediasquaretest/supplemental/no-valid-response.json b/adapters/mediasquare/mediasquaretest/supplemental/no-valid-response.json index 5e987db615..ce2eec4eec 100644 --- a/adapters/mediasquare/mediasquaretest/supplemental/no-valid-response.json +++ b/adapters/mediasquare/mediasquaretest/supplemental/no-valid-response.json @@ -26,6 +26,7 @@ ], "app": null, "device": null, + "site": null, "regs": { "gdpr": null, "ext": { @@ -51,17 +52,18 @@ "uri": "https://pbs-front.mediasquare.fr/msq_prebid", "body": { "codes": null, - "gdpr": { - "consent_string": "", - "consent_required": false - }, + "gdpr": { "consent_required": false, "consent_string": "" }, "type": "pbs", - "dsa": "", + "pbjs": "prebid-test-version", "tech": { - "device": null, - "app": null + "user": { + "ext": { + "consent": null + } + } }, - "test": true + "test": true, + "user_uid": "" }, "impIDs": ["2c35e25e-e7d3-41bf-b810-06a449f456b9"] }, diff --git a/adapters/mediasquare/mediasquaretest/supplemental/status-400.json b/adapters/mediasquare/mediasquaretest/supplemental/status-400.json index 05e4413a97..0541a0fdd8 100644 --- a/adapters/mediasquare/mediasquaretest/supplemental/status-400.json +++ b/adapters/mediasquare/mediasquaretest/supplemental/status-400.json @@ -102,7 +102,7 @@ "consent_required": true }, "type": "pbs", - "dsa": "", + "pbjs": "prebid-test-version", "tech": { "device": { "geo": { @@ -122,9 +122,15 @@ "id": "MEDIA_SQUARE" }, "content": {} + }, + "user": { + "ext": { + "consent": "consent-covering" + } } }, - "test": true + "test": true, + "user_uid": "" }, "impIDs": ["2c35e25e-e7d3-41bf-b810-06a449f456b9"] }, diff --git a/adapters/mediasquare/mediasquaretest/supplemental/status-not-200.json b/adapters/mediasquare/mediasquaretest/supplemental/status-not-200.json index 4168a7adea..f2e91c9581 100644 --- a/adapters/mediasquare/mediasquaretest/supplemental/status-not-200.json +++ b/adapters/mediasquare/mediasquaretest/supplemental/status-not-200.json @@ -102,7 +102,7 @@ "consent_required": true }, "type": "pbs", - "dsa": "", + "pbjs": "prebid-test-version", "tech": { "device": { "geo": { @@ -122,9 +122,15 @@ "id": "MEDIA_SQUARE" }, "content": {} + }, + "user": { + "ext": { + "gdpr": "consent-covering" + } } }, - "test": true + "test": true, + "user_uid": "" }, "impIDs": ["2c35e25e-e7d3-41bf-b810-06a449f456b9"] }, diff --git a/adapters/mediasquare/params_test.go b/adapters/mediasquare/params_test.go index c9d2d5fe01..4906679e28 100644 --- a/adapters/mediasquare/params_test.go +++ b/adapters/mediasquare/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/mediasquare/parsers.go b/adapters/mediasquare/parsers.go index f2ef4ab675..ec531456c1 100644 --- a/adapters/mediasquare/parsers.go +++ b/adapters/mediasquare/parsers.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // parserDSA: Struct used to extracts dsa content of a jsonutil. @@ -24,15 +24,14 @@ func (parser *parserDSA) setContent(extJsonBytes []byte) error { } // getValue: Returns the DSA value as a string, defaultly returns empty-string. -func (parser parserDSA) getValue(request *openrtb2.BidRequest) (dsa string) { +func (parser parserDSA) getValue(request *openrtb2.BidRequest) interface{} { if request == nil || request.Regs == nil { - return + return nil } - parser.setContent(request.Regs.Ext) - if parser.DSA != nil { - dsa = fmt.Sprint(parser.DSA) + if parser.setContent(request.Regs.Ext) != nil { + return nil } - return + return parser.DSA } // parserGDPR: Struct used to extract pair of GDPR/Consent of a jsonutil. @@ -68,9 +67,9 @@ func (parser parserGDPR) getValue(field string, request *openrtb2.BidRequest) (g if request != nil { switch { case field == "consent_requirement" && request.Regs != nil: - gdpr = "false" - if ptrInt8ToBool(request.Regs.GDPR) { - gdpr = "true" + gdpr = "true" + if !ptrInt8ToBool(request.Regs.GDPR) { + gdpr = "false" } case field == "consent_string" && request.User != nil: gdpr = request.User.Consent diff --git a/adapters/mediasquare/structs.go b/adapters/mediasquare/structs.go index 3758e31380..dbda186a28 100644 --- a/adapters/mediasquare/structs.go +++ b/adapters/mediasquare/structs.go @@ -4,8 +4,9 @@ import ( "fmt" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/adapters" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/util/ptrutil" + "github.com/prebid/prebid-server/v4/version" ) // msqResponse: Bid-Response sent by mediasquare. @@ -20,12 +21,14 @@ type msqResponse struct { // msqParameters: Bid-Request sent to mediasquare. type msqParameters struct { - Codes []msqParametersCodes `json:"codes"` - Gdpr msqParametersGdpr `json:"gdpr"` - Type string `json:"type"` - DSA interface{} `json:"dsa,omitempty"` - Support msqSupport `json:"tech"` - Test bool `json:"test"` + Codes []msqParametersCodes `json:"codes"` + Gdpr msqParametersGdpr `json:"gdpr"` + Type string `json:"type"` + PrebidVer string `json:"pbjs,omitempty"` + DSA interface{} `json:"dsa,omitempty"` + Support msqSupport `json:"tech"` + Test bool `json:"test"` + UserUID string `json:"user_uid"` } type msqResponseBidsVideo struct { @@ -83,8 +86,10 @@ type msqResponseBids struct { } type msqSupport struct { - Device interface{} `json:"device"` - App interface{} `json:"app"` + Device *openrtb2.Device `json:"device,omitempty"` + App *openrtb2.App `json:"app,omitempty"` + Site *openrtb2.Site `json:"site,omitempty"` + User *openrtb2.User `json:"user,omitempty"` } type msqParametersCodes struct { @@ -122,13 +127,26 @@ func initMsqParams(request *openrtb2.BidRequest) (msqParams msqParameters) { msqParams.Support = msqSupport{ Device: request.Device, App: request.App, + Site: request.Site, + User: request.User, } msqParams.Gdpr = msqParametersGdpr{ ConsentRequired: (parserGDPR{}).getValue("consent_requirement", request) == "true", ConsentString: (parserGDPR{}).getValue("consent_string", request), } msqParams.DSA = (parserDSA{}).getValue(request) - + if request.User != nil && len(request.User.BuyerUID) > 0 { + msqParams.UserUID = request.User.BuyerUID + } + msqParams.Test = (request.Test == int8(1)) + switch { + case msqParams.Test: + msqParams.PrebidVer = "prebid-test-version" + case len(version.Ver) > 0: + msqParams.PrebidVer = version.Ver + default: + msqParams.PrebidVer = "n/a" + } return } diff --git a/adapters/mediasquare/utils.go b/adapters/mediasquare/utils.go index 50ee7285a7..b2f94d32c6 100644 --- a/adapters/mediasquare/utils.go +++ b/adapters/mediasquare/utils.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) var headerList = map[string][]string{ @@ -87,9 +87,9 @@ func ptrInt8ToBool(i *int8) bool { } // errorWriter: Returns a Custom error message. -func errorWriter(referer string, err error, isEmpty bool) error { +func errorWriter(header string, err error, isEmpty bool) error { if isEmpty { - return fmt.Errorf("%s: is empty.", referer) + return fmt.Errorf("%s: is empty.", header) } - return fmt.Errorf("%s: %s", referer, err.Error()) + return fmt.Errorf("%s: %s", header, err.Error()) } diff --git a/adapters/melozen/melozen.go b/adapters/melozen/melozen.go index d49cc28784..2b9353a253 100644 --- a/adapters/melozen/melozen.go +++ b/adapters/melozen/melozen.go @@ -8,12 +8,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/melozen/melozen_test.go b/adapters/melozen/melozen_test.go index cf6189c6ab..c2db273e18 100644 --- a/adapters/melozen/melozen_test.go +++ b/adapters/melozen/melozen_test.go @@ -3,9 +3,9 @@ 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/melozen/params_test.go b/adapters/melozen/params_test.go index 42a4b38ec8..19d4d2e243 100644 --- a/adapters/melozen/params_test.go +++ b/adapters/melozen/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/metax/metax.go b/adapters/metax/metax.go index 8b19704362..f5e0a3a69f 100644 --- a/adapters/metax/metax.go +++ b/adapters/metax/metax.go @@ -9,13 +9,13 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) type adapter struct { diff --git a/adapters/metax/metax_test.go b/adapters/metax/metax_test.go index f4f9d7e496..74399aada1 100644 --- a/adapters/metax/metax_test.go +++ b/adapters/metax/metax_test.go @@ -5,11 +5,11 @@ import ( "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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/adapters/metax/params_test.go b/adapters/metax/params_test.go index 4487c23326..f0ae81cb73 100644 --- a/adapters/metax/params_test.go +++ b/adapters/metax/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/metax.json diff --git a/adapters/mgid/mgid.go b/adapters/mgid/mgid.go index 68a760a7f5..159475eecc 100644 --- a/adapters/mgid/mgid.go +++ b/adapters/mgid/mgid.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type MgidAdapter struct { diff --git a/adapters/mgid/mgid_test.go b/adapters/mgid/mgid_test.go index 7dc7018b57..50d7792d1b 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mgidX/mgidX.go b/adapters/mgidX/mgidX.go index f952fc27ff..1b123b04d6 100644 --- a/adapters/mgidX/mgidX.go +++ b/adapters/mgidX/mgidX.go @@ -7,10 +7,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/mgidX/mgidX_test.go b/adapters/mgidX/mgidX_test.go index 90ea5c7904..33ea88c0d1 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mgidX/params_test.go b/adapters/mgidX/params_test.go index c5246fba4b..0bc39eafa9 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/minutemedia/minutemedia.go b/adapters/minutemedia/minutemedia.go index f5a212501a..209492527c 100644 --- a/adapters/minutemedia/minutemedia.go +++ b/adapters/minutemedia/minutemedia.go @@ -10,11 +10,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // adapter is a MinuteMedia implementation of the adapters.Bidder interface. diff --git a/adapters/minutemedia/minutemedia_test.go b/adapters/minutemedia/minutemedia_test.go index aa3ce56ca2..577f4388f2 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testsDir = "minutemediatest" diff --git a/adapters/missena/missena.go b/adapters/missena/missena.go index 401f11d159..b620a89972 100644 --- a/adapters/missena/missena.go +++ b/adapters/missena/missena.go @@ -7,13 +7,13 @@ import ( "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/version" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/version" ) type adapter struct { @@ -24,6 +24,7 @@ type MissenaAdRequest struct { Adunit string `json:"adunit,omitempty"` BuyerUID string `json:"buyeruid,omitempty"` Currency string `json:"currency,omitempty"` + Debug bool `json:"debug,omitempty"` EIDs []openrtb2.EID `json:"userEids,omitempty"` Floor float64 `json:"floor,omitempty"` FloorCurrency string `json:"floor_currency,omitempty"` @@ -43,19 +44,19 @@ type BidServerResponse struct { } type UserParams struct { + APIKey string `json:"apiKey,omitempty"` Formats []string `json:"formats,omitempty"` Placement string `json:"placement,omitempty" default:"sticky"` - TestMode string `json:"test,omitempty"` + Sample string `json:"sample,omitempty"` Settings map[string]any `json:"settings,omitempty"` } -type MissenaAdapter struct { - EndpointTemplate *template.Template -} - -var defaultCur = "USD" +const ( + currencyUSD = "USD" + currencyEUR = "EUR" +) -// Builder builds a new instance of the Foo adapter for the given bidder with the given config. +// Builder builds a new instance of the Missena 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 { @@ -67,18 +68,25 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co return bidder, nil } +func getVersionString() string { + if version.Ver == "" { + return version.VerUnknown + } + return version.Ver +} + func getCurrency(currencies []string) (string, error) { eurAvailable := false for _, cur := range currencies { - if cur == defaultCur { - return defaultCur, nil + if cur == currencyUSD { + return currencyUSD, nil } - if cur == "EUR" { + if cur == currencyEUR { eurAvailable = true } } if eurAvailable { - return "EUR", nil + return currencyEUR, nil } return "", fmt.Errorf("no currency supported %v", currencies) } @@ -97,7 +105,7 @@ func (a *adapter) makeRequest(imp openrtb2.Imp, request *openrtb2.BidRequest, re } cur, err := getCurrency(request.Cur) if err != nil { - cur = defaultCur + cur = currencyUSD } var floor float64 @@ -106,7 +114,7 @@ func (a *adapter) makeRequest(imp openrtb2.Imp, request *openrtb2.BidRequest, re floor = imp.BidFloor floorCur, err = getCurrency(request.Cur) if err != nil { - floorCur = defaultCur + floorCur = currencyUSD floor, err = requestInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, floorCur) if err != nil { return nil, err @@ -114,9 +122,20 @@ func (a *adapter) makeRequest(imp openrtb2.Imp, request *openrtb2.BidRequest, re } } + // Extract EIDs from user.ext. Unmarshal errors are intentionally ignored + // to allow requests to proceed without EIDs, as they are optional. + var eids []openrtb2.EID + if request.User != nil && request.User.Ext != nil { + var extUser openrtb_ext.ExtUser + if err := jsonutil.Unmarshal(request.User.Ext, &extUser); err == nil { + eids = extUser.Eids + } + } + missenaRequest := MissenaAdRequest{ Adunit: imp.ID, Currency: cur, + Debug: request.Test == 1, Floor: floor, FloorCurrency: floorCur, IdempotencyKey: request.ID, @@ -124,12 +143,14 @@ func (a *adapter) makeRequest(imp openrtb2.Imp, request *openrtb2.BidRequest, re RequestID: request.ID, Timeout: request.TMax, UserParams: UserParams{ + APIKey: params.APIKey, Formats: params.Formats, Placement: params.Placement, - TestMode: params.TestMode, + Sample: params.Sample, Settings: params.Settings, }, - Version: version.Ver, + EIDs: eids, + Version: fmt.Sprintf("prebid-server@%s", getVersionString()), } body, err := jsonutil.Marshal(missenaRequest) diff --git a/adapters/missena/missena_test.go b/adapters/missena/missena_test.go index 4a858d27c1..e6a4a69038 100644 --- a/adapters/missena/missena_test.go +++ b/adapters/missena/missena_test.go @@ -3,9 +3,9 @@ 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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/missena/missenatest/exemplary/bid-floor-currency.json b/adapters/missena/missenatest/exemplary/bid-floor-currency.json index 940a2451d8..a2601c35bf 100644 --- a/adapters/missena/missenatest/exemplary/bid-floor-currency.json +++ b/adapters/missena/missenatest/exemplary/bid-floor-currency.json @@ -88,9 +88,11 @@ "request_id": "test-request-id", "timeout": 500, "params": { + "apiKey": "test-api-key", "formats": ["banner"], "placement": "sticky" - } + }, + "version": "prebid-server@unknown" }, "impIDs": ["test-imp-id"] }, diff --git a/adapters/missena/missenatest/exemplary/multiple-imps.json b/adapters/missena/missenatest/exemplary/multiple-imps.json index 9f0ea74ce3..2dadd0fee0 100644 --- a/adapters/missena/missenatest/exemplary/multiple-imps.json +++ b/adapters/missena/missenatest/exemplary/multiple-imps.json @@ -144,11 +144,12 @@ } }, "params": { - "placement": "test-placement-1", - "test": "1" + "apiKey": "test-api-key", + "placement": "test-placement-1" }, "request_id": "test-request-id", - "timeout": 500 + "timeout": 500, + "version": "prebid-server@unknown" }, "impIDs": ["test-imp-id-1"] }, diff --git a/adapters/missena/missenatest/exemplary/simple-banner-ipv6.json b/adapters/missena/missenatest/exemplary/simple-banner-ipv6.json index ab279f26b7..3d04e6738a 100644 --- a/adapters/missena/missenatest/exemplary/simple-banner-ipv6.json +++ b/adapters/missena/missenatest/exemplary/simple-banner-ipv6.json @@ -96,11 +96,12 @@ } }, "params": { - "placement": "test-placement", - "test": "1" + "apiKey": "test-api-key", + "placement": "test-placement" }, "request_id": "test-request-id", - "timeout": 500 + "timeout": 500, + "version": "prebid-server@unknown" }, "impIDs": ["test-imp-id"] }, diff --git a/adapters/missena/missenatest/exemplary/simple-banner-with-eids.json b/adapters/missena/missenatest/exemplary/simple-banner-with-eids.json new file mode 100644 index 0000000000..ef3495317f --- /dev/null +++ b/adapters/missena/missenatest/exemplary/simple-banner-with-eids.json @@ -0,0 +1,194 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "tmax": 500, + "at": 1, + "cur": ["EUR"], + "regs": { + "ext": { + "gdpr": 1 + } + }, + "user": { + "ext": { + "consent": "CO-X2XiO_eyUoAsAxBFRBECsA", + "eids": [ + { + "source": "adserver.org", + "uids": [ + { + "id": "111111111111", + "atype": 1 + } + ] + }, + { + "source": "liveramp.com", + "uids": [ + { + "id": "AjfowMv4ZHZQME1RWTn", + "atype": 3 + } + ] + } + ] + } + }, + "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" + } + } + } + ] + }, + "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"], + "Origin": ["https://example.com"] + }, + "body": { + "adunit": "test-imp-id", + "currency": "EUR", + "ik": "test-request-id", + "ortb2": { + "at": 1, + "cur": ["EUR"], + "device": { + "ip": "123.123.123.123", + "ua": "test-user-agent" + }, + "id": "test-request-id", + "imp": [ + { + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": { + "apiKey": "test-api-key", + "placement": "test-placement" + } + }, + "id": "test-imp-id" + } + ], + "regs": { + "ext": { + "gdpr": 1 + } + }, + "site": { + "domain": "example.com", + "page": "https://example.com/page" + }, + "tmax": 500, + "user": { + "ext": { + "consent": "CO-X2XiO_eyUoAsAxBFRBECsA", + "eids": [ + { + "source": "adserver.org", + "uids": [ + { + "id": "111111111111", + "atype": 1 + } + ] + }, + { + "source": "liveramp.com", + "uids": [ + { + "id": "AjfowMv4ZHZQME1RWTn", + "atype": 3 + } + ] + } + ] + } + } + }, + "params": { + "apiKey": "test-api-key", + "placement": "test-placement" + }, + "request_id": "test-request-id", + "timeout": 500, + "userEids": [ + { + "source": "adserver.org", + "uids": [ + { + "id": "111111111111", + "atype": 1 + } + ] + }, + { + "source": "liveramp.com", + "uids": [ + { + "id": "AjfowMv4ZHZQME1RWTn", + "atype": 3 + } + ] + } + ], + "version": "prebid-server@unknown" + }, + "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" + } + ] + } + ] +} diff --git a/adapters/missena/missenatest/exemplary/simple-banner-with-sample.json b/adapters/missena/missenatest/exemplary/simple-banner-with-sample.json new file mode 100644 index 0000000000..4406bf98b2 --- /dev/null +++ b/adapters/missena/missenatest/exemplary/simple-banner-with-sample.json @@ -0,0 +1,137 @@ +{ + "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", + "sample": "test-sample-value" + } + } + } + ] + }, + "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"], + "Origin": ["https://example.com"] + }, + "body": { + "adunit": "test-imp-id", + "currency": "EUR", + "ik": "test-request-id", + "ortb2": { + "at": 1, + "cur": ["EUR"], + "device": { + "ip": "123.123.123.123", + "ua": "test-user-agent" + }, + "id": "test-request-id", + "imp": [ + { + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": { + "apiKey": "test-api-key", + "placement": "test-placement", + "sample": "test-sample-value" + } + }, + "id": "test-imp-id" + } + ], + "regs": { + "ext": { + "gdpr": 1 + } + }, + "site": { + "domain": "example.com", + "page": "https://example.com/page" + }, + "tmax": 500, + "user": { + "ext": { + "consent": "CO-X2XiO_eyUoAsAxBFRBECsA" + } + } + }, + "params": { + "apiKey": "test-api-key", + "placement": "test-placement", + "sample": "test-sample-value" + }, + "request_id": "test-request-id", + "timeout": 500, + "version": "prebid-server@unknown" + }, + "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" + } + ] + } + ] +} diff --git a/adapters/missena/missenatest/exemplary/simple-banner.json b/adapters/missena/missenatest/exemplary/simple-banner.json index e2368579b5..543f0c4995 100644 --- a/adapters/missena/missenatest/exemplary/simple-banner.json +++ b/adapters/missena/missenatest/exemplary/simple-banner.json @@ -94,10 +94,12 @@ } }, "params": { + "apiKey": "test-api-key", "placement": "test-placement" }, "request_id": "test-request-id", - "timeout": 500 + "timeout": 500, + "version": "prebid-server@unknown" }, "impIDs": ["test-imp-id"] }, diff --git a/adapters/missena/missenatest/exemplary/valid-imp-error-imp.json b/adapters/missena/missenatest/exemplary/valid-imp-error-imp.json index 9f0ea74ce3..2dadd0fee0 100644 --- a/adapters/missena/missenatest/exemplary/valid-imp-error-imp.json +++ b/adapters/missena/missenatest/exemplary/valid-imp-error-imp.json @@ -144,11 +144,12 @@ } }, "params": { - "placement": "test-placement-1", - "test": "1" + "apiKey": "test-api-key", + "placement": "test-placement-1" }, "request_id": "test-request-id", - "timeout": 500 + "timeout": 500, + "version": "prebid-server@unknown" }, "impIDs": ["test-imp-id-1"] }, diff --git a/adapters/missena/missenatest/supplemental/status-204.json b/adapters/missena/missenatest/supplemental/status-204.json index 4cd1a24b8a..ab649bb814 100644 --- a/adapters/missena/missenatest/supplemental/status-204.json +++ b/adapters/missena/missenatest/supplemental/status-204.json @@ -96,11 +96,12 @@ } }, "params": { - "placement": "test-placement", - "test": "1" + "apiKey": "test-api-key", + "placement": "test-placement" }, "request_id": "test-request-id", - "timeout": 500 + "timeout": 500, + "version": "prebid-server@unknown" }, "impIDs": ["test-imp-id"] }, diff --git a/adapters/missena/missenatest/supplemental/status-400.json b/adapters/missena/missenatest/supplemental/status-400.json index 616fa05cab..8b0dbf6d77 100644 --- a/adapters/missena/missenatest/supplemental/status-400.json +++ b/adapters/missena/missenatest/supplemental/status-400.json @@ -94,10 +94,12 @@ } }, "params": { + "apiKey": "test-api-key", "placement": "test-placement" }, "request_id": "test-request-id", - "timeout": 500 + "timeout": 500, + "version": "prebid-server@unknown" }, "impIDs": ["test-imp-id"] }, diff --git a/adapters/missena/missenatest/supplemental/status-not-200.json b/adapters/missena/missenatest/supplemental/status-not-200.json index 3dc28ab762..600ae11f62 100644 --- a/adapters/missena/missenatest/supplemental/status-not-200.json +++ b/adapters/missena/missenatest/supplemental/status-not-200.json @@ -96,11 +96,12 @@ } }, "params": { - "placement": "test-placement", - "test": "1" + "apiKey": "test-api-key", + "placement": "test-placement" }, "request_id": "test-request-id", - "timeout": 500 + "timeout": 500, + "version": "prebid-server@unknown" }, "impIDs": ["test-imp-id"] }, diff --git a/adapters/missena/params_test.go b/adapters/missena/params_test.go index 393561b43c..496a44bf8b 100644 --- a/adapters/missena/params_test.go +++ b/adapters/missena/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -36,7 +36,7 @@ func TestInvalidParams(t *testing.T) { var validParams = []string{ `{"apiKey": "PA-123456"}`, `{"apiKey": "PA-123456", "placement": "sticky"}`, - `{"apiKey": "PA-123456", "test": "native"}`, + `{"apiKey": "PA-123456", "sample": "test-sample"}`, } var invalidParams = []string{ @@ -45,6 +45,6 @@ var invalidParams = []string{ `{"placement": 111}`, `{"placement": "sticky"}`, `{"apiKey": "PA-123456", "placement": 111}`, - `{"test": "native"}`, - `{"apiKey": "PA-123456", "test": 111}`, + `{"sample": "test-sample"}`, + `{"apiKey": "PA-123456", "sample": 111}`, } diff --git a/adapters/mobfoxpb/mobfoxpb.go b/adapters/mobfoxpb/mobfoxpb.go index 538e7f7bce..5f9dff28f7 100644 --- a/adapters/mobfoxpb/mobfoxpb.go +++ b/adapters/mobfoxpb/mobfoxpb.go @@ -8,11 +8,11 @@ import ( "github.com/buger/jsonparser" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/adapters/mobfoxpb/mobfoxpb_test.go b/adapters/mobfoxpb/mobfoxpb_test.go index cbcfd29ebc..4a36694e02 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mobfoxpb/params_test.go b/adapters/mobfoxpb/params_test.go index 52b9ffb627..40553b9461 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 88e562b47f..1bcc20b66d 100644 --- a/adapters/mobilefuse/mobilefuse.go +++ b/adapters/mobilefuse/mobilefuse.go @@ -7,25 +7,17 @@ import ( "strconv" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type MobileFuseAdapter struct { Endpoint string } -type ExtMf struct { - MediaType string `json:"media_type"` -} - -type BidExt struct { - Mf ExtMf `json:"mf"` -} - type ExtSkadn struct { Skadn json.RawMessage `json:"skadn"` } @@ -74,10 +66,15 @@ func (adapter *MobileFuseAdapter) MakeBids(incomingRequest *openrtb2.BidRequest, } outgoingBidResponse := adapters.NewBidderResponseWithBidsCapacity(1) - + var errors []error for _, seatbid := range incomingBidResponse.SeatBid { for i := range seatbid.Bid { - bidType := getBidType(seatbid.Bid[i]) + bidType, err := getBidType(seatbid.Bid[i]) + if err != nil { + errors = append(errors, err) + continue + } + seatbid.Bid[i].Ext = nil outgoingBidResponse.Bids = append(outgoingBidResponse.Bids, &adapters.TypedBid{ @@ -87,7 +84,7 @@ func (adapter *MobileFuseAdapter) MakeBids(incomingRequest *openrtb2.BidRequest, } } - return outgoingBidResponse, nil + return outgoingBidResponse, errors } func (adapter *MobileFuseAdapter) makeRequest(bidRequest *openrtb2.BidRequest) (*adapters.RequestData, []error) { @@ -200,18 +197,17 @@ func getValidImps(bidRequest *openrtb2.BidRequest, ext *openrtb_ext.ExtImpMobile return validImps, nil } -func getBidType(bid openrtb2.Bid) openrtb_ext.BidType { - if bid.Ext != nil { - var bidExt BidExt - err := jsonutil.Unmarshal(bid.Ext, &bidExt) - if err == nil { - if bidExt.Mf.MediaType == "video" { - return openrtb_ext.BidTypeVideo - } else if bidExt.Mf.MediaType == "native" { - return openrtb_ext.BidTypeNative - } +func getBidType(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 + default: + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unsupported MType \"%d\" for impression ID \"%s\"", bid.MType, bid.ImpID), } } - - return openrtb_ext.BidTypeBanner } diff --git a/adapters/mobilefuse/mobilefuse_test.go b/adapters/mobilefuse/mobilefuse_test.go index e0a2f3dc23..0d05f27fcc 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps-multi-format.json b/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps-multi-format.json index 039758bd52..1c7a770aa1 100644 --- a/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps-multi-format.json +++ b/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps-multi-format.json @@ -117,11 +117,7 @@ "crid": "test-crid", "h": 50, "w": 320, - "ext": { - "mf": { - "media_type": "banner" - } - } + "mtype": 1 } ] } @@ -143,7 +139,8 @@ "adm": "some-test-ad", "crid": "test-crid", "w": 320, - "h": 50 + "h": 50, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps.json b/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps.json index 4e0206f298..bb1b6d7c30 100644 --- a/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps.json +++ b/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps.json @@ -89,11 +89,7 @@ "crid": "test-crid", "h": 50, "w": 320, - "ext": { - "mf": { - "media_type": "banner" - } - } + "mtype": 1 } ] } @@ -116,7 +112,8 @@ "adm": "some-test-ad", "crid": "test-crid", "w": 320, - "h": 50 + "h": 50, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/mobilefuse/mobilefusetest/exemplary/simple-banner.json b/adapters/mobilefuse/mobilefusetest/exemplary/simple-banner.json index d6b70c5a28..48d9335d62 100644 --- a/adapters/mobilefuse/mobilefusetest/exemplary/simple-banner.json +++ b/adapters/mobilefuse/mobilefusetest/exemplary/simple-banner.json @@ -61,11 +61,7 @@ "crid": "test-crid", "h": 50, "w": 320, - "ext": { - "mf": { - "media_type": "banner" - } - } + "mtype": 1 } ] } @@ -88,7 +84,8 @@ "adm": "some-test-ad", "crid": "test-crid", "w": 320, - "h": 50 + "h": 50, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/mobilefuse/mobilefusetest/exemplary/simple-native.json b/adapters/mobilefuse/mobilefusetest/exemplary/simple-native.json index 8a075d955a..5906b37041 100644 --- a/adapters/mobilefuse/mobilefusetest/exemplary/simple-native.json +++ b/adapters/mobilefuse/mobilefusetest/exemplary/simple-native.json @@ -51,11 +51,7 @@ "crid": "test-crid", "h": 50, "w": 320, - "ext": { - "mf": { - "media_type": "native" - } - } + "mtype": 4 } ] } @@ -77,7 +73,8 @@ "adm": "{\"native\":{\"link\":{\"url\":\"http://mfx.mobilefuse.com/openrtb\"},\"assets\":[{\"id\":0,\"required\":1,\"img\":{\"url\":\"...\"}},{\"id\":1,\"required\":1,\"title\":{\"text\":\"custom title\"}}]}}", "crid": "test-crid", "h": 50, - "w": 320 + "w": 320, + "mtype": 4 }, "type": "native" } diff --git a/adapters/mobilefuse/mobilefusetest/exemplary/simple-video.json b/adapters/mobilefuse/mobilefusetest/exemplary/simple-video.json index 71bfdaf0fe..2dd83841b0 100644 --- a/adapters/mobilefuse/mobilefusetest/exemplary/simple-video.json +++ b/adapters/mobilefuse/mobilefusetest/exemplary/simple-video.json @@ -66,11 +66,7 @@ "crid": "test-crid", "w": 320, "h": 480, - "ext": { - "mf": { - "media_type": "video" - } - } + "mtype": 2 } ] } @@ -91,7 +87,8 @@ "adm": "some-test-ad", "crid": "test-crid", "w": 320, - "h": 480 + "h": 480, + "mtype": 2 }, "type": "video" } diff --git a/adapters/mobilefuse/params_test.go b/adapters/mobilefuse/params_test.go index e585675457..2ef8686ab0 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(test *testing.T) { diff --git a/adapters/mobkoi/mobkoi.go b/adapters/mobkoi/mobkoi.go index 3f8bffe0c5..b9569fd3fa 100644 --- a/adapters/mobkoi/mobkoi.go +++ b/adapters/mobkoi/mobkoi.go @@ -5,10 +5,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { @@ -37,13 +37,11 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte return nil, []error{err} } - if request.Imp[0].TagID == "" { - if ext.Bidder.PlacementID != "" { - request.Imp[0].TagID = ext.Bidder.PlacementID - } else { - return nil, []error{ - errors.New("invalid because it comes with neither request.imp[0].tagId nor req.imp[0].ext.Bidder.placementId"), - } + if ext.Bidder.PlacementID != "" { + request.Imp[0].TagID = ext.Bidder.PlacementID + } else if request.Imp[0].TagID == "" { + return nil, []error{ + errors.New("invalid because it comes with neither request.imp[0].tagId nor req.imp[0].ext.Bidder.placementId"), } } diff --git a/adapters/mobkoi/mobkoi_test.go b/adapters/mobkoi/mobkoi_test.go index 19bcdb8385..6c61fffc71 100644 --- a/adapters/mobkoi/mobkoi_test.go +++ b/adapters/mobkoi/mobkoi_test.go @@ -3,9 +3,9 @@ package mobkoi 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/screencore/screencoretest/exemplary/banner-app.json b/adapters/mobkoi/mobkoitest/exemplary/placement-id-overrides-tagid.json similarity index 65% rename from adapters/screencore/screencoretest/exemplary/banner-app.json rename to adapters/mobkoi/mobkoitest/exemplary/placement-id-overrides-tagid.json index 2c807376f7..99e6f64c46 100644 --- a/adapters/screencore/screencoretest/exemplary/banner-app.json +++ b/adapters/mobkoi/mobkoitest/exemplary/placement-id-overrides-tagid.json @@ -9,31 +9,25 @@ }, "tmax": 1000, "user": { - "buyeruid": "awesome-user" + "buyeruid": "awesome-user", + "consent": "consent-string" }, - "app": { + "site": { + "page": "test.com", "publisher": { "id": "123456789" - }, - "cat": [ - "IAB22-1" - ], - "bundle": "com.app.awesome", - "name": "Awesome App", - "domain": "awesomeapp.com", - "id": "123456789" + } }, "imp": [ { - "id": "1", - "tagid": "ogTAGID", + "id": "some-impression-id1", + "tagid": "originalTagId", "banner": { "w": 320, "h": 50 }, "ext": { "bidder": { - "accountId": "accountId", "placementId": "placementId" } } @@ -45,22 +39,13 @@ "expectedRequest": { "headers": { "Content-Type": [ - "application/json;charset=utf-8" + "application/json" ], "Accept": [ "application/json" - ], - "X-Openrtb-Version": [ - "2.5" - ], - "User-Agent": [ - "test-user-agent" - ], - "X-Forwarded-For": [ - "123.123.123.123" ] }, - "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "uri": "http://dev.mobkoi.com/bid", "body": { "id": "some-request-id", "device": { @@ -71,32 +56,37 @@ }, "imp": [ { - "id": "1", + "id": "some-impression-id1", + "tagid": "placementId", "banner": { "w": 320, "h": 50 }, - "tagid": "ogTAGID" + "ext": { + "bidder": { + "placementId": "placementId" + } + } } ], - "app": { - "id": "123456789", - "name": "Awesome App", - "bundle": "com.app.awesome", - "domain": "awesomeapp.com", - "cat": [ - "IAB22-1" - ], + "site": { + "page": "test.com", "publisher": { "id": "123456789" } }, "user": { - "buyeruid": "awesome-user" + "buyeruid": "awesome-user", + "consent": "consent-string", + "ext": { + "consent": "consent-string" + } }, "tmax": 1000 }, - "impIDs":["1"] + "impIDs": [ + "some-impression-id1" + ] }, "mockResponse": { "status": 200, @@ -107,7 +97,7 @@ "bid": [ { "id": "a3ae1b4e2fc24a4fb45540082e98e161", - "impid": "1", + "impid": "some-impression-id1", "price": 3.5, "adm": "awesome-markup", "adomain": [ @@ -116,11 +106,12 @@ "crid": "20", "w": 320, "h": 50, - "mtype": 1 + "lurl": "mobkoi/loss", + "nurl": "mobkoi/win" } ], "type": "banner", - "seat": "screencore" + "seat": "mobkoi" } ], "cur": "USD" @@ -134,18 +125,20 @@ { "bid": { "id": "a3ae1b4e2fc24a4fb45540082e98e161", - "impid": "1", + "impid": "some-impression-id1", "price": 3.5, "adm": "awesome-markup", + "crid": "20", "adomain": [ "awesome.com" ], - "crid": "20", "w": 320, "h": 50, - "mtype": 1 + "lurl": "mobkoi/loss", + "nurl": "mobkoi/win" }, - "type": "banner" + "type": "banner", + "seat": "mobkoi" } ] } diff --git a/adapters/mobkoi/params_test.go b/adapters/mobkoi/params_test.go index ea279629dc..ad34cedadf 100644 --- a/adapters/mobkoi/params_test.go +++ b/adapters/mobkoi/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(test *testing.T) { diff --git a/adapters/motorik/motorik.go b/adapters/motorik/motorik.go index 5256605ec8..4802d19b0e 100644 --- a/adapters/motorik/motorik.go +++ b/adapters/motorik/motorik.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/motorik/motorik_test.go b/adapters/motorik/motorik_test.go index 5d99d05012..9a94bc633a 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/motorik/params_test.go b/adapters/motorik/params_test.go index 9c8dc2f5d1..5a8dc41891 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/msft/models.go b/adapters/msft/models.go index 625251c773..7a3bf291fb 100644 --- a/adapters/msft/models.go +++ b/adapters/msft/models.go @@ -1,7 +1,7 @@ package msft import ( - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type extraAdapterInfo struct { diff --git a/adapters/msft/msft.go b/adapters/msft/msft.go index c7711dace6..8eae4790cc 100644 --- a/adapters/msft/msft.go +++ b/adapters/msft/msft.go @@ -10,12 +10,12 @@ import ( "github.com/buger/jsonparser" "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/metrics" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) const ( diff --git a/adapters/msft/msft_test.go b/adapters/msft/msft_test.go index b16a8c64b2..6247788282 100644 --- a/adapters/msft/msft_test.go +++ b/adapters/msft/msft_test.go @@ -3,9 +3,9 @@ package msft 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/msft/params_test.go b/adapters/msft/params_test.go index 1046a4a0b2..6c897aafd1 100644 --- a/adapters/msft/params_test.go +++ b/adapters/msft/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file tests static/bidder-params/msft.json diff --git a/adapters/nativery/nativery.go b/adapters/nativery/nativery.go index 1cd05aac12..99a0a4ff5c 100644 --- a/adapters/nativery/nativery.go +++ b/adapters/nativery/nativery.go @@ -6,12 +6,12 @@ import ( "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/metrics" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/nativery/nativery_test.go b/adapters/nativery/nativery_test.go index 4875089fea..0c7bdce2d6 100644 --- a/adapters/nativery/nativery_test.go +++ b/adapters/nativery/nativery_test.go @@ -3,9 +3,9 @@ package nativery 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/nativery/params_test.go b/adapters/nativery/params_test.go index 557c3e0bb9..79f3cb3d0b 100644 --- a/adapters/nativery/params_test.go +++ b/adapters/nativery/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/nativo/nativo.go b/adapters/nativo/nativo.go index 6e595bbff8..b06020a830 100644 --- a/adapters/nativo/nativo.go +++ b/adapters/nativo/nativo.go @@ -1,14 +1,16 @@ package nativo import ( - "encoding/json" "fmt" "net/http" + "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/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { @@ -24,7 +26,7 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co } func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - requestJSON, err := json.Marshal(request) + requestJSON, err := jsonutil.Marshal(request) if err != nil { return nil, []error{err} } @@ -54,32 +56,80 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapte var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { - return nil, []error{err} + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Bad Server Response", + }} } bidResponse := adapters.NewBidderResponse() + // Get the ext from the request + var extReq openrtb_ext.ExtRequest + if len(request.Ext) > 0 { + _ = jsonutil.Unmarshal(request.Ext, &extReq) + } + var errs []error - for _, seatBid := range bidResp.SeatBid { - for i := range seatBid.Bid { - bidType, err := getMediaTypeForImp(seatBid.Bid[i].ImpID, request.Imp) + for seatBidIndex := range bidResp.SeatBid { + seatBid := bidResp.SeatBid[seatBidIndex] + for bidIndex := range seatBid.Bid { + bid := seatBid.Bid[bidIndex] + bidType, err := getMediaTypeForImp(bid.ImpID, request.Imp) + if err != nil { + // Fallback needed in some cases with Prebid SDK + bidType, err = getMediaTypeForBid(bid) + } if err != nil { errs = append(errs, err) continue } b := &adapters.TypedBid{ - Bid: &seatBid.Bid[i], + Bid: &seatBid.Bid[bidIndex], BidType: bidType, + BidMeta: getRendererMeta(&extReq), } - bidResponse.Bids = append(bidResponse.Bids, b) } } return bidResponse, errs } +// Attempt to set NativoRenderer as the meta renderer if it exists in the request ext +func getRendererMeta(ext *openrtb_ext.ExtRequest) *openrtb_ext.ExtBidPrebidMeta { + if ext == nil || ext.Prebid.Sdk == nil { + return nil + } + const rendererName = "NativoRenderer" + for i := range ext.Prebid.Sdk.Renderers { + renderer := &ext.Prebid.Sdk.Renderers[i] + if strings.EqualFold(renderer.Name, rendererName) { + return &openrtb_ext.ExtBidPrebidMeta{ + RendererName: renderer.Name, + RendererVersion: renderer.Version, + } + } + } + return nil +} + +// Get media type from bid response +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 impression \"%s\" mediatype", bid.ImpID), + } +} + +// Get media type from bid request func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { for _, imp := range imps { if imp.ID == impID { diff --git a/adapters/nativo/nativo_test.go b/adapters/nativo/nativo_test.go index 87bce3f08d..3877bb0065 100644 --- a/adapters/nativo/nativo_test.go +++ b/adapters/nativo/nativo_test.go @@ -1,11 +1,16 @@ package nativo import ( + "encoding/json" "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/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestBidderNativo(t *testing.T) { @@ -19,3 +24,244 @@ func TestBidderNativo(t *testing.T) { adapterstest.RunJSONBidderTest(t, "nativotest", bidder) } + +func TestGetRendererMeta(t *testing.T) { + tests := []struct { + description string + ext *openrtb_ext.ExtRequest + expected *openrtb_ext.ExtBidPrebidMeta + }{ + { + description: "nil ext returns nil", + ext: nil, + expected: nil, + }, + { + description: "nil sdk returns nil", + ext: &openrtb_ext.ExtRequest{}, + expected: nil, + }, + { + description: "empty renderers returns nil", + ext: &openrtb_ext.ExtRequest{ + Prebid: openrtb_ext.ExtRequestPrebid{ + Sdk: &openrtb_ext.ExtRequestSdk{}, + }, + }, + expected: nil, + }, + { + description: "NativoRenderer found returns meta with name and version", + ext: &openrtb_ext.ExtRequest{ + Prebid: openrtb_ext.ExtRequestPrebid{ + Sdk: &openrtb_ext.ExtRequestSdk{ + Renderers: []openrtb_ext.ExtRequestSdkRenderer{ + {Name: "NativoRenderer", Version: "1.0"}, + }, + }, + }, + }, + expected: &openrtb_ext.ExtBidPrebidMeta{ + RendererName: "NativoRenderer", + RendererVersion: "1.0", + }, + }, + { + description: "NativoRenderer matched case-insensitively", + ext: &openrtb_ext.ExtRequest{ + Prebid: openrtb_ext.ExtRequestPrebid{ + Sdk: &openrtb_ext.ExtRequestSdk{ + Renderers: []openrtb_ext.ExtRequestSdkRenderer{ + {Name: "nativorenderer", Version: "2.0"}, + }, + }, + }, + }, + expected: &openrtb_ext.ExtBidPrebidMeta{ + RendererName: "nativorenderer", + RendererVersion: "2.0", + }, + }, + { + description: "non-NativoRenderer returns nil", + ext: &openrtb_ext.ExtRequest{ + Prebid: openrtb_ext.ExtRequestPrebid{ + Sdk: &openrtb_ext.ExtRequestSdk{ + Renderers: []openrtb_ext.ExtRequestSdkRenderer{ + {Name: "OtherRenderer", Version: "1.0"}, + }, + }, + }, + }, + expected: nil, + }, + { + description: "NativoRenderer found among multiple renderers", + ext: &openrtb_ext.ExtRequest{ + Prebid: openrtb_ext.ExtRequestPrebid{ + Sdk: &openrtb_ext.ExtRequestSdk{ + Renderers: []openrtb_ext.ExtRequestSdkRenderer{ + {Name: "OtherRenderer", Version: "1.0"}, + {Name: "NativoRenderer", Version: "3.0"}, + }, + }, + }, + }, + expected: &openrtb_ext.ExtBidPrebidMeta{ + RendererName: "NativoRenderer", + RendererVersion: "3.0", + }, + }, + } + + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + result := getRendererMeta(test.ext) + assert.Equal(t, test.expected, result) + }) + } +} + +func TestGetMediaTypeForBid(t *testing.T) { + tests := []struct { + description string + bid openrtb2.Bid + expectedType openrtb_ext.BidType + hasError bool + }{ + { + description: "nil ext returns error", + bid: openrtb2.Bid{ImpID: "test-imp"}, + hasError: true, + }, + { + description: "invalid ext JSON returns error", + bid: openrtb2.Bid{ImpID: "test-imp", Ext: json.RawMessage(`invalid`)}, + hasError: true, + }, + { + description: "ext without prebid field returns error", + bid: openrtb2.Bid{ImpID: "test-imp", Ext: json.RawMessage(`{"other":"data"}`)}, + hasError: true, + }, + { + description: "valid banner type", + bid: openrtb2.Bid{ImpID: "test-imp", Ext: json.RawMessage(`{"prebid":{"type":"banner"}}`)}, + expectedType: openrtb_ext.BidTypeBanner, + }, + { + description: "valid native type", + bid: openrtb2.Bid{ImpID: "test-imp", Ext: json.RawMessage(`{"prebid":{"type":"native"}}`)}, + expectedType: openrtb_ext.BidTypeNative, + }, + { + description: "valid video type", + bid: openrtb2.Bid{ImpID: "test-imp", Ext: json.RawMessage(`{"prebid":{"type":"video"}}`)}, + expectedType: openrtb_ext.BidTypeVideo, + }, + { + description: "unknown bid type string returns error", + bid: openrtb2.Bid{ImpID: "test-imp", Ext: json.RawMessage(`{"prebid":{"type":"unknown"}}`)}, + hasError: true, + }, + } + + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + result, err := getMediaTypeForBid(test.bid) + if test.hasError { + assert.Error(t, err) + assert.Empty(t, result) + } else { + assert.NoError(t, err) + assert.Equal(t, test.expectedType, result) + } + }) + } +} + +func TestGetMediaTypeForImp(t *testing.T) { + tests := []struct { + description string + impID string + imps []openrtb2.Imp + expectedType openrtb_ext.BidType + hasError bool + }{ + { + description: "banner imp", + impID: "test-imp", + imps: []openrtb2.Imp{{ID: "test-imp", Banner: &openrtb2.Banner{}}}, + expectedType: openrtb_ext.BidTypeBanner, + }, + { + description: "video imp", + impID: "test-imp", + imps: []openrtb2.Imp{{ID: "test-imp", Video: &openrtb2.Video{}}}, + expectedType: openrtb_ext.BidTypeVideo, + }, + { + description: "native imp", + impID: "test-imp", + imps: []openrtb2.Imp{{ID: "test-imp", Native: &openrtb2.Native{}}}, + expectedType: openrtb_ext.BidTypeNative, + }, + { + description: "imp not found returns error", + impID: "unknown-imp", + imps: []openrtb2.Imp{{ID: "test-imp", Banner: &openrtb2.Banner{}}}, + hasError: true, + }, + { + description: "imp found but no media type set returns error", + impID: "test-imp", + imps: []openrtb2.Imp{{ID: "test-imp"}}, + hasError: true, + }, + } + + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + result, err := getMediaTypeForImp(test.impID, test.imps) + if test.hasError { + assert.Error(t, err) + assert.Empty(t, result) + } else { + assert.NoError(t, err) + assert.Equal(t, test.expectedType, result) + } + }) + } +} + +func TestMakeBidsNativoRenderer(t *testing.T) { + bidder := &adapter{endpoint: "https://foo.io/?src=prebid"} + + request := &openrtb2.BidRequest{ + ID: "test-request-id", + Imp: []openrtb2.Imp{ + {ID: "test-imp", Banner: &openrtb2.Banner{}}, + }, + Ext: json.RawMessage(`{"prebid":{"sdk":{"renderers":[{"name":"NativoRenderer","version":"1.0.0"}]}}}`), + } + + response := &adapters.ResponseData{ + StatusCode: 200, + Body: json.RawMessage(`{ + "id": "test-response-id", + "seatbid": [{"bid": [{"id": "bid-id", "impid": "test-imp", "price": 3.5}], "seat": "nativo"}], + "cur": "USD" + }`), + } + + bidderResp, errs := bidder.MakeBids(request, nil, response) + + require.Empty(t, errs) + require.Len(t, bidderResp.Bids, 1) + + bid := bidderResp.Bids[0] + assert.Equal(t, openrtb_ext.BidTypeBanner, bid.BidType) + require.NotNil(t, bid.BidMeta) + assert.Equal(t, "NativoRenderer", bid.BidMeta.RendererName) + assert.Equal(t, "1.0.0", bid.BidMeta.RendererVersion) +} diff --git a/adapters/nativo/nativotest/exemplary/banner-app.json b/adapters/nativo/nativotest/exemplary/banner-app.json index 738d01bd9a..29280cbc05 100644 --- a/adapters/nativo/nativotest/exemplary/banner-app.json +++ b/adapters/nativo/nativotest/exemplary/banner-app.json @@ -30,9 +30,26 @@ "banner": { "w": 320, "h": 50 + }, + "ext": { + "bidder": { + "placementId": 12345678 + } } } - ] + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "NativoRenderer", + "version": "1.0.0" + } + ] + } + } + } }, "httpCalls": [ { @@ -53,7 +70,12 @@ "w": 320, "h": 50 }, - "tagid": "ogTAGID" + "tagid": "ogTAGID", + "ext": { + "bidder": { + "placementId": 12345678 + } + } } ], "app": { @@ -71,7 +93,19 @@ "user": { "buyeruid": "awesome-user" }, - "tmax": 1000 + "tmax": 1000, + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "NativoRenderer", + "version": "1.0.0" + } + ] + } + } + } }, "impIDs":["some-impression-id"] }, @@ -92,7 +126,15 @@ ], "crid": "20", "w": 320, - "h": 50 + "h": 50, + "ext": { + "prebid": { + "meta": { + "rendererName": "NativoRenderer", + "rendererVersion": "1.0.0" + } + } + } } ], "seat": "nativo" @@ -123,7 +165,15 @@ ], "crid": "20", "w": 320, - "h": 50 + "h": 50, + "ext": { + "prebid": { + "meta": { + "rendererName": "NativoRenderer", + "rendererVersion": "1.0.0" + } + } + } }, "type": "banner" } diff --git a/adapters/nativo/nativotest/exemplary/banner-web-no-placementid.json b/adapters/nativo/nativotest/exemplary/banner-web-no-placementid.json new file mode 100644 index 0000000000..d4c3d38a00 --- /dev/null +++ b/adapters/nativo/nativotest/exemplary/banner-web-no-placementid.json @@ -0,0 +1,121 @@ +{ + "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", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": {} + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://foo.io/?src=prebid", + "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", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": {} + } + } + ], + "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": 320, + "h": 50 + } + ], + "seat": "nativo" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "w": 320, + "h": 50 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/screencore/screencoretest/exemplary/video-web.json b/adapters/nativo/nativotest/exemplary/banner-web-string-placementid.json similarity index 60% rename from adapters/screencore/screencoretest/exemplary/video-web.json rename to adapters/nativo/nativotest/exemplary/banner-web-string-placementid.json index 47de396e8c..a26662fed2 100644 --- a/adapters/screencore/screencoretest/exemplary/video-web.json +++ b/adapters/nativo/nativotest/exemplary/banner-web-string-placementid.json @@ -21,19 +21,13 @@ { "id": "some-impression-id", "tagid": "ogTAGID", - "video": { - "mimes": [ - "video/mp4" - ], - "w": 640, - "h": 480, - "minduration": 120, - "maxduration": 150 + "banner": { + "w": 320, + "h": 50 }, "ext": { "bidder": { - "accountId": "accountId", - "placementId": "placementId" + "placementId": "12345678" } } } @@ -42,24 +36,7 @@ "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://h1.screencore.io/?kp=accountId&kn=placementId", + "uri": "https://foo.io/?src=prebid", "body": { "id": "some-request-id", "device": { @@ -72,14 +49,14 @@ { "id": "some-impression-id", "tagid": "ogTAGID", - "video": { - "mimes": [ - "video/mp4" - ], - "minduration": 120, - "maxduration": 150, - "w": 640, - "h": 480 + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "placementId": "12345678" + } } } ], @@ -94,7 +71,7 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": ["some-impression-id"] }, "mockResponse": { "status": 200, @@ -112,17 +89,11 @@ "awesome.com" ], "crid": "20", - "w": 1280, - "h": 720, - "ext": { - "prebid": { - "type": "video" - } - }, - "mtype": 2 + "w": 320, + "h": 50 } ], - "seat": "screencore" + "seat": "nativo" } ], "cur": "USD" @@ -139,22 +110,16 @@ "impid": "some-impression-id", "price": 3.5, "adm": "awesome-markup", + "crid": "20", "adomain": [ "awesome.com" ], - "crid": "20", - "w": 1280, - "h": 720, - "ext": { - "prebid": { - "type": "video" - } - }, - "mtype": 2 + "w": 320, + "h": 50 }, - "type": "video" + "type": "banner" } ] } ] -} \ No newline at end of file +} diff --git a/adapters/nativo/nativotest/exemplary/banner-web.json b/adapters/nativo/nativotest/exemplary/banner-web.json index 58af89b202..ce67bbd15f 100644 --- a/adapters/nativo/nativotest/exemplary/banner-web.json +++ b/adapters/nativo/nativotest/exemplary/banner-web.json @@ -24,6 +24,11 @@ "banner": { "w":320, "h":50 + }, + "ext": { + "bidder": { + "placementId": 12345678 + } } } ] @@ -47,6 +52,11 @@ "banner": { "w":320, "h":50 + }, + "ext": { + "bidder": { + "placementId": 12345678 + } } } ], diff --git a/adapters/nativo/nativotest/exemplary/native-app.json b/adapters/nativo/nativotest/exemplary/native-app.json index 5f038958b7..5f3e5a730d 100644 --- a/adapters/nativo/nativotest/exemplary/native-app.json +++ b/adapters/nativo/nativotest/exemplary/native-app.json @@ -30,9 +30,26 @@ "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": { + "placementId": 12345678 + } } } - ] + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "NativoRenderer", + "version": "1.0.0" + } + ] + } + } + } }, "httpCalls": [ { @@ -53,7 +70,12 @@ "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" + "tagid": "ogTAGID", + "ext": { + "bidder": { + "placementId": 12345678 + } + } } ], "app": { @@ -71,7 +93,19 @@ "user": { "buyeruid": "awesome-user" }, - "tmax": 1000 + "tmax": 1000, + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "NativoRenderer", + "version": "1.0.0" + } + ] + } + } + } }, "impIDs":["some-impression-id"] }, @@ -90,7 +124,15 @@ "adomain": [ "awesome.com" ], - "crid": "20" + "crid": "20", + "ext": { + "prebid": { + "meta": { + "rendererName": "NativoRenderer", + "rendererVersion": "1.0.0" + } + } + } } ], "seat": "nativo" @@ -119,7 +161,15 @@ "crid": "20", "adomain": [ "awesome.com" - ] + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "NativoRenderer", + "rendererVersion": "1.0.0" + } + } + } }, "type": "native" } diff --git a/adapters/nativo/nativotest/exemplary/native-web.json b/adapters/nativo/nativotest/exemplary/native-web.json index 598dc2abfc..98e0ca38df 100644 --- a/adapters/nativo/nativotest/exemplary/native-web.json +++ b/adapters/nativo/nativotest/exemplary/native-web.json @@ -24,6 +24,11 @@ "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": { + "placementId": 12345678 + } } } ] @@ -47,6 +52,11 @@ "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": { + "placementId": 12345678 + } } } ], diff --git a/adapters/nativo/nativotest/exemplary/video-app.json b/adapters/nativo/nativotest/exemplary/video-app.json index 596bf9bcaf..2a478e2526 100644 --- a/adapters/nativo/nativotest/exemplary/video-app.json +++ b/adapters/nativo/nativotest/exemplary/video-app.json @@ -35,9 +35,26 @@ "h": 480, "minduration": 120, "maxduration": 150 + }, + "ext": { + "bidder": { + "placementId": 12345678 + } } } - ] + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "NativoRenderer", + "version": "1.0.0" + } + ] + } + } + } }, "httpCalls": [ { @@ -63,7 +80,12 @@ "w": 640, "h": 480 }, - "tagid": "ogTAGID" + "tagid": "ogTAGID", + "ext": { + "bidder": { + "placementId": 12345678 + } + } } ], "app": { @@ -81,7 +103,19 @@ "user": { "buyeruid": "awesome-user" }, - "tmax": 1000 + "tmax": 1000, + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "NativoRenderer", + "version": "1.0.0" + } + ] + } + } + } }, "impIDs":["some-impression-id"] }, @@ -102,7 +136,15 @@ ], "crid": "20", "w": 1280, - "h": 720 + "h": 720, + "ext": { + "prebid": { + "meta": { + "rendererName": "NativoRenderer", + "rendererVersion": "1.0.0" + } + } + } } ], "seat": "nativo" @@ -133,7 +175,15 @@ "awesome.com" ], "w": 1280, - "h": 720 + "h": 720, + "ext": { + "prebid": { + "meta": { + "rendererName": "NativoRenderer", + "rendererVersion": "1.0.0" + } + } + } }, "type": "video" } diff --git a/adapters/nativo/nativotest/exemplary/video-web.json b/adapters/nativo/nativotest/exemplary/video-web.json index 12e185ca15..a1043b2136 100644 --- a/adapters/nativo/nativotest/exemplary/video-web.json +++ b/adapters/nativo/nativotest/exemplary/video-web.json @@ -29,6 +29,11 @@ "h": 480, "minduration": 120, "maxduration": 150 + }, + "ext": { + "bidder": { + "placementId": 12345678 + } } } ] @@ -57,6 +62,11 @@ "maxduration": 150, "w": 640, "h": 480 + }, + "ext": { + "bidder": { + "placementId": 12345678 + } } } ], diff --git a/adapters/nativo/nativotest/supplemental/200-different-impID-response-from-nativo.json b/adapters/nativo/nativotest/supplemental/200-different-impID-response-from-nativo.json index 320d7f5e1b..96e4b3e875 100755 --- a/adapters/nativo/nativotest/supplemental/200-different-impID-response-from-nativo.json +++ b/adapters/nativo/nativotest/supplemental/200-different-impID-response-from-nativo.json @@ -13,7 +13,9 @@ ] }, "ext": { - "bidder": {} + "bidder": { + "placementId": "12345678" + } } } ] @@ -36,7 +38,9 @@ ] }, "ext": { - "bidder": {} + "bidder": { + "placementId": "12345678" + } } } ] @@ -74,7 +78,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "Unrecognized impression type in response from nativo: nativo-id-2", + "value": "Failed to parse impression \"nativo-id-2\" mediatype", "comparison": "literal" } ] diff --git a/adapters/nativo/nativotest/supplemental/400-response-from-nativo.json b/adapters/nativo/nativotest/supplemental/400-response-from-nativo.json index f5ebb6024c..342ad1a243 100755 --- a/adapters/nativo/nativotest/supplemental/400-response-from-nativo.json +++ b/adapters/nativo/nativotest/supplemental/400-response-from-nativo.json @@ -13,7 +13,9 @@ ] }, "ext": { - "bidder": {} + "bidder": { + "placementId": 12345678 + } } } ] @@ -36,7 +38,9 @@ ] }, "ext": { - "bidder": {} + "bidder": { + "placementId": 12345678 + } } } ] diff --git a/adapters/nativo/nativotest/supplemental/500-response-from-nativo.json b/adapters/nativo/nativotest/supplemental/500-response-from-nativo.json index cc58f18ece..c111cf3edd 100755 --- a/adapters/nativo/nativotest/supplemental/500-response-from-nativo.json +++ b/adapters/nativo/nativotest/supplemental/500-response-from-nativo.json @@ -13,7 +13,9 @@ ] }, "ext": { - "bidder": {} + "bidder": { + "placementId": 12345678 + } } } ] @@ -36,7 +38,9 @@ ] }, "ext": { - "bidder": {} + "bidder": { + "placementId": 12345678 + } } } ] diff --git a/adapters/nativo/nativotest/supplemental/bid-type-fallback-invalid-type.json b/adapters/nativo/nativotest/supplemental/bid-type-fallback-invalid-type.json new file mode 100644 index 0000000000..2a6c36c019 --- /dev/null +++ b/adapters/nativo/nativotest/supplemental/bid-type-fallback-invalid-type.json @@ -0,0 +1,91 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "nativo-id", + "banner": { + "format": [ + { + "w": 300, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "placementId": 12345678 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://foo.io/?src=prebid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "nativo-id", + "banner": { + "format": [ + { + "w": 300, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "placementId": 12345678 + } + } + } + ] + }, + "impIDs": ["nativo-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid-id", + "impid": "nativo-id-2", + "price": 3.5, + "adm": "awesome-markup", + "w": 300, + "h": 50, + "ext": { + "prebid": { + "type": "unknown" + } + } + } + ], + "seat": "nativo" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "invalid BidType: unknown", + "comparison": "literal" + } + ] +} diff --git a/adapters/nativo/nativotest/supplemental/bid-type-fallback-native.json b/adapters/nativo/nativotest/supplemental/bid-type-fallback-native.json new file mode 100644 index 0000000000..3eec53f1bc --- /dev/null +++ b/adapters/nativo/nativotest/supplemental/bid-type-fallback-native.json @@ -0,0 +1,92 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "nativo-id", + "native": { + "request": "" + }, + "ext": { + "bidder": { + "placementId": 12345678 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://foo.io/?src=prebid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "nativo-id", + "native": { + "request": "" + }, + "ext": { + "bidder": { + "placementId": 12345678 + } + } + } + ] + }, + "impIDs": ["nativo-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid-id", + "impid": "nativo-id-2", + "price": 3.5, + "adm": "awesome-markup", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + } + ], + "seat": "nativo" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-id", + "impid": "nativo-id-2", + "price": 3.5, + "adm": "awesome-markup", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/nativo/nativotest/supplemental/bid-type-fallback-success.json b/adapters/nativo/nativotest/supplemental/bid-type-fallback-success.json new file mode 100644 index 0000000000..286fa30ae7 --- /dev/null +++ b/adapters/nativo/nativotest/supplemental/bid-type-fallback-success.json @@ -0,0 +1,102 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "nativo-id", + "banner": { + "format": [ + { + "w": 300, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "placementId": 12345678 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://foo.io/?src=prebid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "nativo-id", + "banner": { + "format": [ + { + "w": 300, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "placementId": 12345678 + } + } + } + ] + }, + "impIDs": ["nativo-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid-id", + "impid": "nativo-id-2", + "price": 3.5, + "adm": "awesome-markup", + "w": 300, + "h": 50, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "nativo" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-id", + "impid": "nativo-id-2", + "price": 3.5, + "adm": "awesome-markup", + "w": 300, + "h": 50, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/nativo/nativotest/supplemental/bid-type-fallback-video.json b/adapters/nativo/nativotest/supplemental/bid-type-fallback-video.json new file mode 100644 index 0000000000..9bbab6b643 --- /dev/null +++ b/adapters/nativo/nativotest/supplemental/bid-type-fallback-video.json @@ -0,0 +1,96 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "nativo-id", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "placementId": 12345678 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://foo.io/?src=prebid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "nativo-id", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "placementId": 12345678 + } + } + } + ] + }, + "impIDs": ["nativo-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid-id", + "impid": "nativo-id-2", + "price": 5.0, + "adm": "awesome-video-markup", + "w": 640, + "h": 480, + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "nativo" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-id", + "impid": "nativo-id-2", + "price": 5.0, + "adm": "awesome-video-markup", + "w": 640, + "h": 480, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/adsinteractive/adsinteractivetest/supplemental/bad-response.json b/adapters/nativo/nativotest/supplemental/malformed-response-body.json similarity index 70% rename from adapters/adsinteractive/adsinteractivetest/supplemental/bad-response.json rename to adapters/nativo/nativotest/supplemental/malformed-response-body.json index 3f40cfa351..c49a72cb1e 100644 --- a/adapters/adsinteractive/adsinteractivetest/supplemental/bad-response.json +++ b/adapters/nativo/nativotest/supplemental/malformed-response-body.json @@ -3,61 +3,59 @@ "id": "test-request-id", "imp": [ { - "id": "test-imp-id", + "id": "nativo-id", "banner": { "format": [ { "w": 300, - "h": 250 + "h": 50 } ] }, "ext": { "bidder": { - "adUnit": "fake-adunit-name" + "placementId": 12345678 } } } ] }, - "httpCalls": [ { "expectedRequest": { - "uri": "http://bid.adsinteractive.com/prebid", + "uri": "https://foo.io/?src=prebid", "body": { "id": "test-request-id", "imp": [ { - "id": "test-imp-id", + "id": "nativo-id", "banner": { "format": [ { "w": 300, - "h": 250 + "h": 50 } ] }, "ext": { "bidder": { - "adUnit": "fake-adunit-name" + "placementId": 12345678 } } } ] }, - "impIDs":["test-imp-id"] + "impIDs": ["nativo-id"] }, "mockResponse": { "status": 200, - "body": "" + "body": "invalid-body" } } ], - "expectedMakeBidsErrors": [ { - "value": "expect { or n, but found \"", + "value": "Bad Server Response", "comparison": "literal" } ] diff --git a/adapters/nativo/nativotest/supplemental/nativo-renderer-in-request.json b/adapters/nativo/nativotest/supplemental/nativo-renderer-in-request.json new file mode 100644 index 0000000000..4d03e79af2 --- /dev/null +++ b/adapters/nativo/nativotest/supplemental/nativo-renderer-in-request.json @@ -0,0 +1,116 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "nativo-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": 12345678 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "NativoRenderer", + "version": "1.0.0" + } + ] + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://foo.io/?src=prebid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "nativo-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": 12345678 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "NativoRenderer", + "version": "1.0.0" + } + ] + } + } + } + }, + "impIDs": ["nativo-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid-id", + "impid": "nativo-id", + "price": 3.5, + "adm": "awesome-markup", + "w": 300, + "h": 250 + } + ], + "seat": "nativo" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-id", + "impid": "nativo-id", + "price": 3.5, + "adm": "awesome-markup", + "w": 300, + "h": 250 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/nativo/params_test.go b/adapters/nativo/params_test.go new file mode 100644 index 0000000000..8d8cc8a4a8 --- /dev/null +++ b/adapters/nativo/params_test.go @@ -0,0 +1,44 @@ +package nativo + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/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.BidderNativo, 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-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderNativo, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"placementId": "12345678"}`, + `{"placementId": 12345678}`, + `{}`, +} + +var invalidParams = []string{ + `{"placementId": false}`, +} diff --git a/adapters/nextmillennium/nextmillennium.go b/adapters/nextmillennium/nextmillennium.go index 1b2546b662..c678b39eda 100644 --- a/adapters/nextmillennium/nextmillennium.go +++ b/adapters/nextmillennium/nextmillennium.go @@ -6,12 +6,12 @@ import ( "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" - "github.com/prebid/prebid-server/v3/version" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/version" ) const NM_ADAPTER_VERSION = "v1.0.1" diff --git a/adapters/nextmillennium/nextmillennium_test.go b/adapters/nextmillennium/nextmillennium_test.go index 1ffe49540b..da32f73484 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/nextmillennium/params_test.go b/adapters/nextmillennium/params_test.go index 3833c474a3..fcfab8e41d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index f91961918c..4d63524ba6 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -7,12 +7,12 @@ import ( "net/url" "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" - "github.com/prebid/prebid-server/v3/version" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/version" ) type adapter struct { @@ -66,11 +66,27 @@ func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, plac } } - impExt := Ext{ - Nexx360: bidderExt.Bidder, + // Unmarshal entire ext to preserve all fields + var impExtMap map[string]interface{} + if err := jsonutil.Unmarshal(imp.Ext, &impExtMap); err != nil { + return nil, "", "", &errortypes.BadInput{ + Message: err.Error(), + } } - impExtJSON, err := json.Marshal(impExt) + // Unmarshal nexx360 bidder params to a map for merging + var nexx360ExtMap map[string]interface{} + if err := jsonutil.Unmarshal(bidderExt.Bidder, &nexx360ExtMap); err != nil { + return nil, "", "", &errortypes.BadInput{ + Message: err.Error(), + } + } + + // Replace bidder field with nexx360 field + delete(impExtMap, "bidder") + impExtMap["nexx360"] = nexx360ExtMap + + impExtJSON, err := jsonutil.Marshal(impExtMap) if err != nil { return nil, "", "", &errortypes.BadInput{ Message: err.Error(), diff --git a/adapters/nexx360/nexx360_test.go b/adapters/nexx360/nexx360_test.go index f7a8741f17..e66cc24219 100644 --- a/adapters/nexx360/nexx360_test.go +++ b/adapters/nexx360/nexx360_test.go @@ -3,9 +3,9 @@ package nexx360 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/nexx360/nexx360test/exemplary/simple-banner-with-extra-ext.json b/adapters/nexx360/nexx360test/exemplary/simple-banner-with-extra-ext.json new file mode 100644 index 0000000000..704f8ebc6c --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-banner-with-extra-ext.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "tagId": "testnexx" + }, + "gpid": "/1111/homepage", + "ae": 1, + "data": { + "pbadslot": "homepage-top" + }, + "skadn": { + "version": "2.0", + "sourceapp": "123456789" + } + } + } + ], + "site": {}, + "ext": { + "nexx360": "Prebid-Server", + "test": 1 + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "body": { + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "nexx360": { + "tagId": "testnexx" + }, + "gpid": "/1111/homepage", + "ae": 1, + "data": { + "pbadslot": "homepage-top" + }, + "skadn": { + "version": "2.0", + "sourceapp": "123456789" + } + } + } + ], + "site": {} + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "testalias", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-banner", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-banner", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/nexx360/params_test.go b/adapters/nexx360/params_test.go index dc21d21134..45b4c38d96 100644 --- a/adapters/nexx360/params_test.go +++ b/adapters/nexx360/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/nexx360.json diff --git a/adapters/nobid/nobid.go b/adapters/nobid/nobid.go index 811ef3363e..12be203e5c 100644 --- a/adapters/nobid/nobid.go +++ b/adapters/nobid/nobid.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // NoBidAdapter - NoBid Adapter definition diff --git a/adapters/nobid/nobid_test.go b/adapters/nobid/nobid_test.go index 6b4a7346cf..ad117b4c80 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/nobid/params_test.go b/adapters/nobid/params_test.go index 375237f344..27acf08d21 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/ogury/ogury.go b/adapters/ogury/ogury.go index 7207ff2ac9..a97923da06 100644 --- a/adapters/ogury/ogury.go +++ b/adapters/ogury/ogury.go @@ -8,11 +8,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { @@ -87,15 +87,10 @@ func (a adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapter } if len(impsWithOguryParams) == 0 { - if request.Site != nil && (request.Site.Publisher == nil || request.Site.Publisher.ID == "") { + if !hasPublisherId(request) { // we can serve ads with publisherId+adunitcode combination return nil, []error{&errortypes.BadInput{ - Message: "Invalid request. assetKey/adUnitId or request.site.publisher.id required", - }} - } else if request.App != nil { - // for app request there is no adunitcode equivalent so we can't serve ads with just the publisher id - return nil, []error{&errortypes.BadInput{ - Message: "Invalid request. assetKey/adUnitId required", + Message: "Invalid request. assetKey/adUnitId or request.site/app.publisher.id required", }} } } else if len(impsWithOguryParams) > 0 { @@ -149,6 +144,18 @@ func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { } } +func hasPublisherId(request *openrtb2.BidRequest) bool { + return hasSitePublisherId(request) || hasAppPublisherId(request) +} + +func hasSitePublisherId(request *openrtb2.BidRequest) bool { + return request.Site != nil && request.Site.Publisher != nil && request.Site.Publisher.ID != "" +} + +func hasAppPublisherId(request *openrtb2.BidRequest) bool { + return request.App != nil && request.App.Publisher != nil && request.App.Publisher.ID != "" +} + func (a adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { if adapters.IsResponseStatusCodeNoContent(responseData) { return nil, nil diff --git a/adapters/ogury/ogury_test.go b/adapters/ogury/ogury_test.go index 504be6ccaa..2c57b27d39 100644 --- a/adapters/ogury/ogury_test.go +++ b/adapters/ogury/ogury_test.go @@ -3,9 +3,9 @@ package ogury 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/ogury/ogurytest/exemplary/app_banner_publisher.json b/adapters/ogury/ogurytest/exemplary/app_banner_publisher.json new file mode 100644 index 0000000000..6a19c07729 --- /dev/null +++ b/adapters/ogury/ogurytest/exemplary/app_banner_publisher.json @@ -0,0 +1,97 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.example", + "publisher": { + "id": "pub-id" + } + }, + "imp": [ + { + "id": "imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://ogury.example.com", + "body": { + "app": { + "id": "1", + "bundle": "com.example", + "publisher": { + "id": "pub-id" + } + }, + "id": "test-request-id", + "imp": [ + { + "id":"imp-id", + "tagid": "imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + } + } + ] + }, + "impIDs":["imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "seat", + "bid": [{ + "id": "some-UUID", + "impid": "imp-id", + "price": 0.500000, + "nurl": "example nurl", + "adm": "adm string", + "crid": "crid_10", + "h": 100, + "w": 128, + "mtype": 1 + }] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "some-UUID", + "impid": "imp-id", + "price": 0.5, + "nurl": "example nurl", + "adm": "adm string", + "crid": "crid_10", + "h": 100, + "w": 128, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/ogury/ogurytest/supplemental/app_banner_invalid_request.json b/adapters/ogury/ogurytest/supplemental/app_banner_invalid_request.json index 36f7948bc1..274258f9fa 100644 --- a/adapters/ogury/ogurytest/supplemental/app_banner_invalid_request.json +++ b/adapters/ogury/ogurytest/supplemental/app_banner_invalid_request.json @@ -3,10 +3,7 @@ "id": "test-request-id", "app": { "id": "1", - "bundle": "com.example", - "publisher": { - "id": "pub-id" - } + "bundle": "com.example" }, "imp": [ { @@ -26,7 +23,7 @@ "expectedBidResponses": [], "expectedMakeRequestsErrors": [{ - "value": "Invalid request. assetKey/adUnitId required", + "value": "Invalid request. assetKey/adUnitId or request.site/app.publisher.id required", "comparison": "literal" }] } diff --git a/adapters/ogury/ogurytest/supplemental/site_banner_invalid_request.json b/adapters/ogury/ogurytest/supplemental/site_banner_invalid_request.json index e26875ba07..c385c9f1e6 100644 --- a/adapters/ogury/ogurytest/supplemental/site_banner_invalid_request.json +++ b/adapters/ogury/ogurytest/supplemental/site_banner_invalid_request.json @@ -22,7 +22,7 @@ "httpCalls": [], "expectedBidResponses": [], "expectedMakeRequestsErrors": [{ - "value": "Invalid request. assetKey/adUnitId or request.site.publisher.id required", + "value": "Invalid request. assetKey/adUnitId or request.site/app.publisher.id required", "comparison": "literal" }] } diff --git a/adapters/ogury/param_test.go b/adapters/ogury/param_test.go index f4c7c83445..b48b22cb33 100644 --- a/adapters/ogury/param_test.go +++ b/adapters/ogury/param_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/oms/oms.go b/adapters/oms/oms.go index 3ea5bd3284..3e4e8ff392 100644 --- a/adapters/oms/oms.go +++ b/adapters/oms/oms.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/oms/oms_test.go b/adapters/oms/oms_test.go index e0555b3c75..d0d14fe1eb 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/oms/params_test.go b/adapters/oms/params_test.go index ed4113d423..300c2058d0 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 d1b2e6238e..efa38c631e 100644 --- a/adapters/onetag/onetag.go +++ b/adapters/onetag/onetag.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/onetag/onetag_test.go b/adapters/onetag/onetag_test.go index 23a2871758..f7c64ef3f9 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/onetag/params_test.go b/adapters/onetag/params_test.go index 6ccf060696..3d6021a5dc 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/openweb/openweb.go b/adapters/openweb/openweb.go index 7a9914b272..5d8e770cf3 100644 --- a/adapters/openweb/openweb.go +++ b/adapters/openweb/openweb.go @@ -10,11 +10,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/openweb/openweb_test.go b/adapters/openweb/openweb_test.go index a08788e7db..51b2305c6f 100644 --- a/adapters/openweb/openweb_test.go +++ b/adapters/openweb/openweb_test.go @@ -3,9 +3,9 @@ package openweb 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/openweb/params_test.go b/adapters/openweb/params_test.go index 73fb20a7e9..622816033c 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/openweb.json diff --git a/adapters/openx/openx.go b/adapters/openx/openx.go index 992baa0cdc..5148ffde25 100644 --- a/adapters/openx/openx.go +++ b/adapters/openx/openx.go @@ -7,11 +7,11 @@ import ( "strconv" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const hbconfig = "hb_pbs_1.0.0" diff --git a/adapters/openx/openx_test.go b/adapters/openx/openx_test.go index fdfb37cc4a..dd320b717f 100644 --- a/adapters/openx/openx_test.go +++ b/adapters/openx/openx_test.go @@ -6,10 +6,10 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/openx/params_test.go b/adapters/openx/params_test.go index 0becd9b206..1fc71fce7e 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/openx.json diff --git a/adapters/operaads/operaads.go b/adapters/operaads/operaads.go index 47c372beca..448c4843a6 100644 --- a/adapters/operaads/operaads.go +++ b/adapters/operaads/operaads.go @@ -8,13 +8,13 @@ import ( "strings" "text/template" - "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/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/prebid/openrtb/v20/openrtb2" ) diff --git a/adapters/operaads/operaads_test.go b/adapters/operaads/operaads_test.go index 8614e77e7e..b5e21bd8cd 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/operaads/params_test.go b/adapters/operaads/params_test.go index b845fde89b..a20d374942 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/operaads.json diff --git a/adapters/optidigital/optidigital.go b/adapters/optidigital/optidigital.go index 89e2474d97..a59cd2a73a 100644 --- a/adapters/optidigital/optidigital.go +++ b/adapters/optidigital/optidigital.go @@ -4,11 +4,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/optidigital/optidigital_test.go b/adapters/optidigital/optidigital_test.go index dda8b09b54..d89bb92e0c 100644 --- a/adapters/optidigital/optidigital_test.go +++ b/adapters/optidigital/optidigital_test.go @@ -3,9 +3,9 @@ package optidigital 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/optidigital/params_test.go b/adapters/optidigital/params_test.go index 5c29d9796d..cb5c9329f2 100644 --- a/adapters/optidigital/params_test.go +++ b/adapters/optidigital/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/optidigital.json diff --git a/adapters/oraki/oraki.go b/adapters/oraki/oraki.go index db6876f2e0..49a970d934 100644 --- a/adapters/oraki/oraki.go +++ b/adapters/oraki/oraki.go @@ -6,10 +6,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/oraki/oraki_test.go b/adapters/oraki/oraki_test.go index 753357c29f..e37922fb1b 100644 --- a/adapters/oraki/oraki_test.go +++ b/adapters/oraki/oraki_test.go @@ -3,9 +3,9 @@ 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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/oraki/params_test.go b/adapters/oraki/params_test.go index 24fc6ea29e..3e8ca92e90 100644 --- a/adapters/oraki/params_test.go +++ b/adapters/oraki/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/orbidder/orbidder.go b/adapters/orbidder/orbidder.go index b2f6705273..980ffdde3e 100644 --- a/adapters/orbidder/orbidder.go +++ b/adapters/orbidder/orbidder.go @@ -8,11 +8,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type OrbidderAdapter struct { diff --git a/adapters/orbidder/orbidder_test.go b/adapters/orbidder/orbidder_test.go index ce26bdd7f2..1b29f988fb 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/orbidder/params_test.go b/adapters/orbidder/params_test.go index bb557faa2c..9f8d316b18 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 612a9a0cbe..dfcc2ec378 100644 --- a/adapters/outbrain/outbrain.go +++ b/adapters/outbrain/outbrain.go @@ -8,11 +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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/outbrain/outbrain_test.go b/adapters/outbrain/outbrain_test.go index 1e1fc1e803..84b347df51 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/outbrain/params_test.go b/adapters/outbrain/params_test.go index e6d76d9472..9df86a4e15 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/ownadx/ownadx.go b/adapters/ownadx/ownadx.go index 737adfa30d..f01048d812 100644 --- a/adapters/ownadx/ownadx.go +++ b/adapters/ownadx/ownadx.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/ownadx/ownadx_test.go b/adapters/ownadx/ownadx_test.go index 6921e1ba12..6f979f185c 100644 --- a/adapters/ownadx/ownadx_test.go +++ b/adapters/ownadx/ownadx_test.go @@ -3,9 +3,9 @@ package ownadx 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/pangle/pangle.go b/adapters/pangle/pangle.go index a86052d649..76ad2cc8b6 100644 --- a/adapters/pangle/pangle.go +++ b/adapters/pangle/pangle.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/pangle/pangle_test.go b/adapters/pangle/pangle_test.go index 2143d4f90a..5e52025f02 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pangle/param_test.go b/adapters/pangle/param_test.go index 57acfb0609..57adb0d8f1 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/pgamssp/params_test.go b/adapters/pgamssp/params_test.go index ec95d47e5f..fd8962b04e 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/pgamssp/pgamssp.go b/adapters/pgamssp/pgamssp.go index 6ddf21159e..a74719d08c 100644 --- a/adapters/pgamssp/pgamssp.go +++ b/adapters/pgamssp/pgamssp.go @@ -7,10 +7,10 @@ import ( "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/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/pgamssp/pgamssp_test.go b/adapters/pgamssp/pgamssp_test.go index 450eb0f0b5..691e8cbb8a 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pixfuture/params_test.go b/adapters/pixfuture/params_test.go new file mode 100644 index 0000000000..19f2438f65 --- /dev/null +++ b/adapters/pixfuture/params_test.go @@ -0,0 +1,71 @@ +package pixfuture + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + require.NoError(t, err, "Failed to fetch the json schema.") + + tests := []struct { + name string + json string + }{ + { + name: "Minimum length satisfied", + json: `{"pix_id": "1"}`, + }, + { + name: "Longer valid string", + json: `{"pix_id": "abcdef"}`, + }, + } + + for _, tt := range tests { + tt := tt // capture range variable + t.Run(tt.name, func(t *testing.T) { + assert.NoErrorf(t, validator.Validate(openrtb_ext.BidderPixfuture, json.RawMessage(tt.json)), "Schema rejected valid params: %s", tt.json) + }) + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + require.NoError(t, err, "Failed to fetch the json schema.") + + tests := []struct { + name string + json string + }{ + { + name: "Wrong type (integer)", + json: `{"pix_id": 123}`, + }, + { + name: "Missing required pix_id", + json: `{}`, + }, + { + name: "Empty string (violates minLength)", + json: `{"pix_id": ""}`, + }, + { + name: "Unknown field (additionalProperties: false)", + json: `{"pix_id": "123", "unknown_field": "anything"}`, + }, + } + + for _, tt := range tests { + tt := tt // capture range variable + t.Run(tt.name, func(t *testing.T) { + err := validator.Validate(openrtb_ext.BidderPixfuture, json.RawMessage(tt.json)) + assert.Errorf(t, err, "Schema allowed invalid params: %s", tt.json) + }) + } +} diff --git a/adapters/pixfuture/pixfuture.go b/adapters/pixfuture/pixfuture.go new file mode 100644 index 0000000000..47cebb45a2 --- /dev/null +++ b/adapters/pixfuture/pixfuture.go @@ -0,0 +1,134 @@ +// Package pixfuture implements the Pixfuture adapter for Prebid Server. +// It provides functionality to handle bid requests and responses according to Pixfuture's specifications +package pixfuture + +import ( + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/iterutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + return &adapter{ + endpoint: config.Endpoint, + }, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + + var errs []error + var adapterRequests []*adapters.RequestData + + for imp := range iterutil.SlicePointerValues(request.Imp) { + headers := http.Header{} + headers.Set("Content-Type", "application/json") + headers.Set("Accept", "application/json") + + requestCopy := *request + requestCopy.Imp = []openrtb2.Imp{*imp} // slice notation with dereferencing + + reqJSON, err := jsonutil.Marshal(requestCopy) + if err != nil { + errs = append(errs, err) + continue + } + + adapterRequests = append(adapterRequests, &adapters.RequestData{ + Method: http.MethodPost, + Uri: a.endpoint, + Body: reqJSON, + Headers: headers, + ImpIDs: []string{imp.ID}, + }) + } + + if len(adapterRequests) == 0 && len(errs) > 0 { + return nil, errs + } + return adapterRequests, errs +} + +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 + // Step 1: Check if body is empty to avoid unnecessary unmarshal overhead + if len(response.Body) == 0 { + return nil, nil // Or return a specific error if Pixfuture always expects a body + } + + // Step 2: The Unmarshal call (Lines 88-92) + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("Invalid response format: %s", err.Error()), + }} + } + + // Pre-calculate total number of bids // + expectedBids := 0 + for i := range bidResp.SeatBid { + expectedBids += len(bidResp.SeatBid[i].Bid) + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(expectedBids) + if bidResp.Cur != "" { + bidResponse.Currency = bidResp.Cur + } + + var errs []error + for i := range bidResp.SeatBid { + // Use index j to avoid copying the large openrtb2.Bid struct + for j := range bidResp.SeatBid[i].Bid { + bid := &bidResp.SeatBid[i].Bid[j] + + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errs = append(errs, err) + continue + } + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: bid, + BidType: bidType, + }) + } + } + + if len(bidResponse.Bids) == 0 { + return nil, errs + } + + return bidResponse, errs +} + +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 + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Failed to parse bid mediatype for impression %s from MType", bid.ImpID), + } + } +} diff --git a/adapters/pixfuture/pixfuture_test.go b/adapters/pixfuture/pixfuture_test.go new file mode 100644 index 0000000000..0dfbaf0efa --- /dev/null +++ b/adapters/pixfuture/pixfuture_test.go @@ -0,0 +1,19 @@ +package pixfuture + +import ( + "testing" + + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/require" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderPixfuture, config.Adapter{ + Endpoint: "http://any.url", + }, config.Server{}) + require.NoError(t, buildErr, "Builder returned unexpected error") + + adapterstest.RunJSONBidderTest(t, "pixfuturetest", bidder) +} diff --git a/adapters/pixfuture/pixfuturetest/exemplary/banner-site.json b/adapters/pixfuture/pixfuturetest/exemplary/banner-site.json new file mode 100644 index 0000000000..fcbc4ceea5 --- /dev/null +++ b/adapters/pixfuture/pixfuturetest/exemplary/banner-site.json @@ -0,0 +1,113 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://any.url", + "headers": { + "Content-Type": [ + "application/json" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + } + ] + }, + "impIDs": [ + "imp1" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "
Banner Ad
", + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "
Banner Ad
", + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ], + "currency": "USD" + } + ] +} diff --git a/adapters/pixfuture/pixfuturetest/exemplary/multiimp.json b/adapters/pixfuture/pixfuturetest/exemplary/multiimp.json new file mode 100644 index 0000000000..f89c979cb6 --- /dev/null +++ b/adapters/pixfuture/pixfuturetest/exemplary/multiimp.json @@ -0,0 +1,209 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + }, + { + "id": "imp2", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "pix_id": "55464" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://any.url", + "headers": { + "Content-Type": [ + "application/json" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + } + ] + }, + "impIDs": [ + "imp1" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id-1", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "
Banner Ad 1
", + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + }, + { + "expectedRequest": { + "uri": "http://any.url", + "headers": { + "Content-Type": [ + "application/json" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "imp2", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "pix_id": "55464" + } + } + } + ] + }, + "impIDs": [ + "imp2" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id-2", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid2", + "impid": "imp2", + "price": 2.34, + "adm": "
Banner Ad 2
", + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "
Banner Ad 1
", + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ], + "currency": "USD" + }, + { + "bids": [ + { + "bid": { + "id": "bid2", + "impid": "imp2", + "price": 2.34, + "adm": "
Banner Ad 2
", + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ], + "currency": "USD" + } + ] +} diff --git a/adapters/pixfuture/pixfuturetest/exemplary/native.json b/adapters/pixfuture/pixfuturetest/exemplary/native.json new file mode 100644 index 0000000000..9052af00bd --- /dev/null +++ b/adapters/pixfuture/pixfuturetest/exemplary/native.json @@ -0,0 +1,95 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":1,\"assets\":[]}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://any.url", + "headers": { + "Content-Type": ["application/json"], + "Accept": ["application/json"] + }, + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":1,\"assets\":[]}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + } + ] + }, + "impIDs": ["imp1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "{\"ver\":\"1.2\",\"native\":{\"assets\":[]}}", + "mtype": 4, + "ext": { + "prebid": { + "type": "native" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "{\"ver\":\"1.2\",\"native\":{\"assets\":[]}}", + "mtype": 4, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ], + "currency": "USD" + } + ] +} diff --git a/adapters/pixfuture/pixfuturetest/exemplary/video-app.json b/adapters/pixfuture/pixfuturetest/exemplary/video-app.json new file mode 100644 index 0000000000..d790349cfa --- /dev/null +++ b/adapters/pixfuture/pixfuturetest/exemplary/video-app.json @@ -0,0 +1,103 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "app1" + }, + "imp": [ + { + "id": "imp1", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://any.url", + "headers": { + "Content-Type": ["application/json"], + "Accept": ["application/json"] + }, + "body": { + "id": "test-request-id", + "app": { + "id": "app1" + }, + "imp": [ + { + "id": "imp1", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + } + ] + }, + "impIDs": ["imp1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ], + "currency": "USD" + } + ] +} diff --git a/adapters/pixfuture/pixfuturetest/exemplary/video.json b/adapters/pixfuture/pixfuturetest/exemplary/video.json new file mode 100644 index 0000000000..62c0dcd6f8 --- /dev/null +++ b/adapters/pixfuture/pixfuturetest/exemplary/video.json @@ -0,0 +1,97 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://any.url", + "headers": { + "Content-Type": ["application/json"], + "Accept": ["application/json"] + }, + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + } + ] + }, + "impIDs": ["imp1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ], + "currency": "USD" + } + ] +} diff --git a/adapters/pixfuture/pixfuturetest/supplemental/bad_status.json b/adapters/pixfuture/pixfuturetest/supplemental/bad_status.json new file mode 100644 index 0000000000..4cd7ffb3fd --- /dev/null +++ b/adapters/pixfuture/pixfuturetest/supplemental/bad_status.json @@ -0,0 +1,60 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://any.url", + "headers": { + "Content-Type": ["application/json"], + "Accept": ["application/json"] + }, + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "123" + } + } + } + ] + }, + "impIDs": ["imp1"] + }, + "mockResponse": { + "status": 400, + "headers": {}, + "body": "Bad Request" + } + } + ], + "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/pixfuture/pixfuturetest/supplemental/no_bids.json b/adapters/pixfuture/pixfuturetest/supplemental/no_bids.json new file mode 100644 index 0000000000..5f2ccb6748 --- /dev/null +++ b/adapters/pixfuture/pixfuturetest/supplemental/no_bids.json @@ -0,0 +1,54 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://any.url", + "headers": { + "Content-Type": ["application/json"], + "Accept": ["application/json"] + }, + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "123" + } + } + } + ] + }, + "impIDs": ["imp1"] + }, + "mockResponse": { + "status": 204, + "headers": {}, + "body": "" + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/pixfuture/pixfuturetest/supplemental/no_cur_in_response.json b/adapters/pixfuture/pixfuturetest/supplemental/no_cur_in_response.json new file mode 100644 index 0000000000..7a1da098bb --- /dev/null +++ b/adapters/pixfuture/pixfuturetest/supplemental/no_cur_in_response.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://any.url", + "headers": { + "Content-Type": [ + "application/json" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "55463" + } + } + } + ] + }, + "impIDs": [ + "imp1" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "
Banner Ad
", + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "
Banner Ad
", + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ], + "currency": "USD" + } + ] +} diff --git a/adapters/pixfuture/pixfuturetest/supplemental/status_204.json b/adapters/pixfuture/pixfuturetest/supplemental/status_204.json new file mode 100644 index 0000000000..5f2ccb6748 --- /dev/null +++ b/adapters/pixfuture/pixfuturetest/supplemental/status_204.json @@ -0,0 +1,54 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://any.url", + "headers": { + "Content-Type": ["application/json"], + "Accept": ["application/json"] + }, + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "123" + } + } + } + ] + }, + "impIDs": ["imp1"] + }, + "mockResponse": { + "status": 204, + "headers": {}, + "body": "" + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/pixfuture/pixfuturetest/supplemental/unknown_type.json b/adapters/pixfuture/pixfuturetest/supplemental/unknown_type.json new file mode 100644 index 0000000000..e1551cc1c9 --- /dev/null +++ b/adapters/pixfuture/pixfuturetest/supplemental/unknown_type.json @@ -0,0 +1,83 @@ +{ + "description": "Tests an unknown bid type response", + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://any.url", + "headers": { + "Content-Type": ["application/json"], + "Accept": ["application/json"] + }, + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "imp1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pix_id": "123" + } + } + } + ] + }, + "impIDs": ["imp1"] + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json"] + }, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid1", + "impid": "imp1", + "price": 1.23, + "adm": "
Ad
", + "ext": { + "prebid": { + "type": "unknown" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Failed to parse bid mediatype for impression imp1 from MType", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/playdigo/params_test.go b/adapters/playdigo/params_test.go index cb0fa0c681..f586019b45 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/playdigo/playdigo.go b/adapters/playdigo/playdigo.go index fe0091e2cb..578e39ae7b 100644 --- a/adapters/playdigo/playdigo.go +++ b/adapters/playdigo/playdigo.go @@ -7,10 +7,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/playdigo/playdigo_test.go b/adapters/playdigo/playdigo_test.go index 275924f193..0318659595 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/proxistore/params_test.go b/adapters/proxistore/params_test.go new file mode 100644 index 0000000000..0d2f987f50 --- /dev/null +++ b/adapters/proxistore/params_test.go @@ -0,0 +1,47 @@ +package proxistore + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + require.NoError(t, err, "Failed to fetch the json schema. %v", err) + + for _, p := range validParams { + err := validator.Validate(openrtb_ext.BidderProxistore, json.RawMessage(p)) + assert.NoError(t, err, "Schema rejected valid params: %s", p) + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + require.NoError(t, err, "Failed to fetch the json schema. %v", err) + + for _, p := range invalidParams { + err := validator.Validate(openrtb_ext.BidderProxistore, json.RawMessage(p)) + assert.Error(t, err, "Schema allowed invalid params: %s", p) + } +} + +var validParams = []string{ + `{"website": "example.com", "language": "fr"}`, + `{"website": "test-site", "language": "en"}`, + `{"website": "publisher.be", "language": "nl"}`, +} + +var invalidParams = []string{ + `{}`, + `{"website": "example.com"}`, + `{"language": "fr"}`, + `{"website": "", "language": "fr"}`, + `{"website": "example.com", "language": ""}`, + `{"website": 123, "language": "fr"}`, + `{"website": "example.com", "language": 456}`, + `null`, +} diff --git a/adapters/proxistore/proxistore.go b/adapters/proxistore/proxistore.go new file mode 100644 index 0000000000..9952f1bc4c --- /dev/null +++ b/adapters/proxistore/proxistore.go @@ -0,0 +1,97 @@ +package proxistore + +import ( + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +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 := jsonutil.Marshal(request) + if err != nil { + return nil, []error{err} + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json") + headers.Add("Accept", "application/json") + headers.Add("X-Prebid-Source", "server") + + 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(request.Imp)) + bidResponse.Currency = response.Cur + + var errors []error + for _, seatBid := range response.SeatBid { + for i, bid := range seatBid.Bid { + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errors = append(errors, err) + continue + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + }) + } + } + + return bidResponse, 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 + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, 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), + } + } +} diff --git a/adapters/proxistore/proxistore_test.go b/adapters/proxistore/proxistore_test.go new file mode 100644 index 0000000000..826607ecae --- /dev/null +++ b/adapters/proxistore/proxistore_test.go @@ -0,0 +1,27 @@ +package proxistore + +import ( + "testing" + + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder( + openrtb_ext.BidderProxistore, + config.Adapter{ + Endpoint: "https://api.proxistore.com/v3/rtb/openrtb", + }, + config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 1, + DataCenter: "2", + }, + ) + + assert.NoError(t, buildErr) + adapterstest.RunJSONBidderTest(t, "proxistoretest", bidder) +} diff --git a/adapters/proxistore/proxistoretest/exemplary/multi-imp-banner.json b/adapters/proxistore/proxistoretest/exemplary/multi-imp-banner.json new file mode 100644 index 0000000000..cab78da49b --- /dev/null +++ b/adapters/proxistore/proxistoretest/exemplary/multi-imp-banner.json @@ -0,0 +1,151 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0" + }, + "site": { + "domain": "example.com", + "page": "https://example.com/page" + }, + "imp": [ + { + "id": "imp-1", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + }, + { + "id": "imp-2", + "banner": { + "format": [{"w": 728, "h": 90}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.proxistore.com/v3/rtb/openrtb", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0" + }, + "site": { + "domain": "example.com", + "page": "https://example.com/page" + }, + "imp": [ + { + "id": "imp-1", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + }, + { + "id": "imp-2", + "banner": { + "format": [{"w": 728, "h": 90}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "impIDs": ["imp-1", "imp-2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid-1", + "impid": "imp-1", + "price": 1.50, + "adm": "
Ad 1
", + "crid": "creative-1", + "w": 300, + "h": 250, + "mtype": 1 + }, + { + "id": "bid-2", + "impid": "imp-2", + "price": 0.80, + "adm": "
Ad 2
", + "crid": "creative-2", + "w": 728, + "h": 90, + "mtype": 1 + } + ], + "seat": "proxistore" + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "imp-1", + "price": 1.50, + "adm": "
Ad 1
", + "crid": "creative-1", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "bid-2", + "impid": "imp-2", + "price": 0.80, + "adm": "
Ad 2
", + "crid": "creative-2", + "w": 728, + "h": 90, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/proxistore/proxistoretest/exemplary/simple-audio.json b/adapters/proxistore/proxistoretest/exemplary/simple-audio.json new file mode 100644 index 0000000000..4bcea39364 --- /dev/null +++ b/adapters/proxistore/proxistoretest/exemplary/simple-audio.json @@ -0,0 +1,108 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "site": { + "id": "site-id", + "domain": "example.com", + "page": "https://example.com/page" + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": ["audio/mp3"], + "minduration": 5, + "maxduration": 30 + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.proxistore.com/v3/rtb/openrtb", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "site": { + "id": "site-id", + "domain": "example.com", + "page": "https://example.com/page" + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": ["audio/mp3"], + "minduration": 5, + "maxduration": 30 + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.50, + "adm": "", + "adomain": ["advertiser.com"], + "crid": "creative-audio-123", + "mtype": 3 + } + ], + "seat": "proxistore" + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.50, + "adm": "", + "adomain": ["advertiser.com"], + "crid": "creative-audio-123", + "mtype": 3 + }, + "type": "audio" + } + ] + } + ] +} diff --git a/adapters/proxistore/proxistoretest/exemplary/simple-banner-app.json b/adapters/proxistore/proxistoretest/exemplary/simple-banner-app.json new file mode 100644 index 0000000000..bfc01eca1c --- /dev/null +++ b/adapters/proxistore/proxistoretest/exemplary/simple-banner-app.json @@ -0,0 +1,138 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36" + }, + "app": { + "id": "app-id", + "bundle": "com.example.app", + "name": "Example App", + "domain": "example.com", + "publisher": { + "id": "pub-123" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + {"w": 320, "h": 50}, + {"w": 300, "h": 250} + ] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ], + "regs": { + "gdpr": 1 + }, + "user": { + "ext": { + "consent": "COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.proxistore.com/v3/rtb/openrtb", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36" + }, + "app": { + "id": "app-id", + "bundle": "com.example.app", + "name": "Example App", + "domain": "example.com", + "publisher": { + "id": "pub-123" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + {"w": 320, "h": 50}, + {"w": 300, "h": 250} + ] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ], + "regs": { + "gdpr": 1 + }, + "user": { + "ext": { + "consent": "COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.85, + "adm": "
App banner creative
", + "adomain": ["advertiser.com"], + "crid": "creative-456", + "w": 320, + "h": 50, + "mtype": 1 + } + ], + "seat": "proxistore" + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.85, + "adm": "
App banner creative
", + "adomain": ["advertiser.com"], + "crid": "creative-456", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/proxistore/proxistoretest/exemplary/simple-banner.json b/adapters/proxistore/proxistoretest/exemplary/simple-banner.json new file mode 100644 index 0000000000..a3006eed94 --- /dev/null +++ b/adapters/proxistore/proxistoretest/exemplary/simple-banner.json @@ -0,0 +1,130 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "site": { + "id": "site-id", + "domain": "example.com", + "page": "https://example.com/page" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + {"w": 300, "h": 250}, + {"w": 300, "h": 600} + ] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ], + "regs": { + "gdpr": 1 + }, + "user": { + "ext": { + "consent": "COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.proxistore.com/v3/rtb/openrtb", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "site": { + "id": "site-id", + "domain": "example.com", + "page": "https://example.com/page" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + {"w": 300, "h": 250}, + {"w": 300, "h": 600} + ] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ], + "regs": { + "gdpr": 1 + }, + "user": { + "ext": { + "consent": "COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.23, + "adm": "
Ad creative
", + "adomain": ["advertiser.com"], + "crid": "creative-123", + "w": 300, + "h": 250, + "mtype": 1 + } + ], + "seat": "proxistore" + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.23, + "adm": "
Ad creative
", + "adomain": ["advertiser.com"], + "crid": "creative-123", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/proxistore/proxistoretest/exemplary/simple-native.json b/adapters/proxistore/proxistoretest/exemplary/simple-native.json new file mode 100644 index 0000000000..b0146495cd --- /dev/null +++ b/adapters/proxistore/proxistoretest/exemplary/simple-native.json @@ -0,0 +1,104 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "site": { + "id": "site-id", + "domain": "example.com", + "page": "https://example.com/page" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.1\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":90}}]}" + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.proxistore.com/v3/rtb/openrtb", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "site": { + "id": "site-id", + "domain": "example.com", + "page": "https://example.com/page" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.1\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":90}}]}" + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.80, + "adm": "{\"native\":{\"ver\":\"1.1\",\"link\":{\"url\":\"https://example.com\"},\"assets\":[{\"id\":1,\"title\":{\"text\":\"Ad Title\"}}]}}", + "adomain": ["advertiser.com"], + "crid": "creative-native-123", + "mtype": 4 + } + ], + "seat": "proxistore" + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.80, + "adm": "{\"native\":{\"ver\":\"1.1\",\"link\":{\"url\":\"https://example.com\"},\"assets\":[{\"id\":1,\"title\":{\"text\":\"Ad Title\"}}]}}", + "adomain": ["advertiser.com"], + "crid": "creative-native-123", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/proxistore/proxistoretest/exemplary/simple-video.json b/adapters/proxistore/proxistoretest/exemplary/simple-video.json new file mode 100644 index 0000000000..192eb60295 --- /dev/null +++ b/adapters/proxistore/proxistoretest/exemplary/simple-video.json @@ -0,0 +1,118 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "site": { + "id": "site-id", + "domain": "example.com", + "page": "https://example.com/page" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [1, 2], + "w": 640, + "h": 480, + "minduration": 5, + "maxduration": 30 + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.proxistore.com/v3/rtb/openrtb", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "site": { + "id": "site-id", + "domain": "example.com", + "page": "https://example.com/page" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [1, 2], + "w": 640, + "h": 480, + "minduration": 5, + "maxduration": 30 + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.50, + "adm": "", + "adomain": ["advertiser.com"], + "crid": "creative-video-123", + "w": 640, + "h": 480, + "mtype": 2 + } + ], + "seat": "proxistore" + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.50, + "adm": "", + "adomain": ["advertiser.com"], + "crid": "creative-video-123", + "w": 640, + "h": 480, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/proxistore/proxistoretest/supplemental/bad-response.json b/adapters/proxistore/proxistoretest/supplemental/bad-response.json new file mode 100644 index 0000000000..850d729e25 --- /dev/null +++ b/adapters/proxistore/proxistoretest/supplemental/bad-response.json @@ -0,0 +1,61 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.proxistore.com/v3/rtb/openrtb", + "body": { + "id": "test-request-id", + "site": { + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": "not valid json" + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} diff --git a/adapters/proxistore/proxistoretest/supplemental/status-204.json b/adapters/proxistore/proxistoretest/supplemental/status-204.json new file mode 100644 index 0000000000..1375e9c65f --- /dev/null +++ b/adapters/proxistore/proxistoretest/supplemental/status-204.json @@ -0,0 +1,55 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.proxistore.com/v3/rtb/openrtb", + "body": { + "id": "test-request-id", + "site": { + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/proxistore/proxistoretest/supplemental/status-400.json b/adapters/proxistore/proxistoretest/supplemental/status-400.json new file mode 100644 index 0000000000..ef772ce672 --- /dev/null +++ b/adapters/proxistore/proxistoretest/supplemental/status-400.json @@ -0,0 +1,61 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.proxistore.com/v3/rtb/openrtb", + "body": { + "id": "test-request-id", + "site": { + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/proxistore/proxistoretest/supplemental/status-500.json b/adapters/proxistore/proxistoretest/supplemental/status-500.json new file mode 100644 index 0000000000..b8595ed9db --- /dev/null +++ b/adapters/proxistore/proxistoretest/supplemental/status-500.json @@ -0,0 +1,61 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.proxistore.com/v3/rtb/openrtb", + "body": { + "id": "test-request-id", + "site": { + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 500, + "body": {} + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/proxistore/proxistoretest/supplemental/unsupported-mtype.json b/adapters/proxistore/proxistoretest/supplemental/unsupported-mtype.json new file mode 100644 index 0000000000..5141e24f1d --- /dev/null +++ b/adapters/proxistore/proxistoretest/supplemental/unsupported-mtype.json @@ -0,0 +1,86 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.proxistore.com/v3/rtb/openrtb", + "body": { + "id": "test-request-id", + "site": { + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "website": "example.com", + "language": "fr" + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.23, + "adm": "
Ad creative
", + "crid": "creative-123", + "w": 300, + "h": 250, + "mtype": 99 + } + ], + "seat": "proxistore" + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unsupported MType 99 for bid test-bid-id", + "comparison": "literal" + } + ] +} diff --git a/adapters/pubmatic/params_test.go b/adapters/pubmatic/params_test.go index 531416f187..5ca06fdaf9 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 e35229143c..ebc6634090 100644 --- a/adapters/pubmatic/pubmatic.go +++ b/adapters/pubmatic/pubmatic.go @@ -9,12 +9,12 @@ import ( "strconv" "strings" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" diff --git a/adapters/pubmatic/pubmatic_test.go b/adapters/pubmatic/pubmatic_test.go index ac1e645c19..de7afcd4d4 100644 --- a/adapters/pubmatic/pubmatic_test.go +++ b/adapters/pubmatic/pubmatic_test.go @@ -8,11 +8,11 @@ import ( "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/errortypes" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/adapters/pubnative/pubnative.go b/adapters/pubnative/pubnative.go index 7c77aeefc9..b30912d257 100644 --- a/adapters/pubnative/pubnative.go +++ b/adapters/pubnative/pubnative.go @@ -8,12 +8,12 @@ import ( "strconv" "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" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) type PubnativeAdapter struct { diff --git a/adapters/pubnative/pubnative_test.go b/adapters/pubnative/pubnative_test.go index dfc065b716..c4e8613b8d 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pubrise/params_test.go b/adapters/pubrise/params_test.go index 97ee8ebc5c..4422295bd7 100644 --- a/adapters/pubrise/params_test.go +++ b/adapters/pubrise/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/pubrise/pubrise.go b/adapters/pubrise/pubrise.go index 80168f9725..2c4b11e5c3 100644 --- a/adapters/pubrise/pubrise.go +++ b/adapters/pubrise/pubrise.go @@ -7,10 +7,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/pubrise/pubrise_test.go b/adapters/pubrise/pubrise_test.go index 9f4f2124ab..abccfafddc 100644 --- a/adapters/pubrise/pubrise_test.go +++ b/adapters/pubrise/pubrise_test.go @@ -3,9 +3,9 @@ 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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pulsepoint/params_test.go b/adapters/pulsepoint/params_test.go index 4359c4115a..56cf4139c0 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/pulsepoint/pulsepoint.go b/adapters/pulsepoint/pulsepoint.go index 2f750e9f85..11dd7533a4 100644 --- a/adapters/pulsepoint/pulsepoint.go +++ b/adapters/pulsepoint/pulsepoint.go @@ -7,11 +7,11 @@ import ( "net/http" "strconv" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) diff --git a/adapters/pulsepoint/pulsepoint_test.go b/adapters/pulsepoint/pulsepoint_test.go index be9fff83a6..fb766aab8c 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pwbid/params_test.go b/adapters/pwbid/params_test.go index 52f06e0257..a57cf6baea 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/pwbid/pwbid.go b/adapters/pwbid/pwbid.go index 7e03185f2c..6cd6b9ea6e 100644 --- a/adapters/pwbid/pwbid.go +++ b/adapters/pwbid/pwbid.go @@ -5,11 +5,11 @@ import ( "fmt" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/pwbid/pwbid_test.go b/adapters/pwbid/pwbid_test.go index cb028a19f6..3a9e76e2b6 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/qt/params_test.go b/adapters/qt/params_test.go index 5c8d3253be..0b46b55067 100644 --- a/adapters/qt/params_test.go +++ b/adapters/qt/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/qt/qt.go b/adapters/qt/qt.go index a7c5d53c5a..1a1a96acbe 100644 --- a/adapters/qt/qt.go +++ b/adapters/qt/qt.go @@ -6,10 +6,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/qt/qt_test.go b/adapters/qt/qt_test.go index f85adbaf18..3da46eb223 100644 --- a/adapters/qt/qt_test.go +++ b/adapters/qt/qt_test.go @@ -3,9 +3,9 @@ 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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/readpeak/params_test.go b/adapters/readpeak/params_test.go index 772855e425..d71396eb35 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/readpeak/readpeak.go b/adapters/readpeak/readpeak.go index 7049dace48..5aaf8c9d80 100644 --- a/adapters/readpeak/readpeak.go +++ b/adapters/readpeak/readpeak.go @@ -8,11 +8,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/readpeak/readpeak_test.go b/adapters/readpeak/readpeak_test.go index 8c8e8e27be..9f4feb20c1 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/rediads/params_test.go b/adapters/rediads/params_test.go index af69698237..13ba386eff 100644 --- a/adapters/rediads/params_test.go +++ b/adapters/rediads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -36,9 +36,25 @@ func TestInvalidParams(t *testing.T) { var validParams = []string{ `{"account_id": "123"}`, `{"account_id": "123", "slot": "12345"}`, - `{"account_id": "123", "slot": "12345", "endpoint": "https://bidding.rediads.com/openrtb2/auction"}`, + `{"account_id": "123", "slot": "12345", "endpoint": "bidding2"}`, + `{"account_id": "123", "endpoint": "host"}`, + `{"account_id": "123", "endpoint": "host.example.com"}`, + `{"account_id": "123", "endpoint": "host-example.test"}`, + `{"account_id": "123", "endpoint": "Host.Example.com"}`, + `{"account_id": "123", "endpoint": "localhost"}`, } var invalidParams = []string{ - `{"account": 42}`, `{}`, + `{"account": 42}`, + `{}`, + `{"account_id": "123", "endpoint": "/path"}`, + `{"account_id": "123", "endpoint": "//evil.com"}`, + `{"account_id": "123", "endpoint": "host/path"}`, + `{"account_id": "123", "endpoint": "host?query=1"}`, + `{"account_id": "123", "endpoint": "host#fragment"}`, + `{"account_id": "123", "endpoint": "user@host"}`, + `{"account_id": "123", "endpoint": "https://host.com"}`, + `{"account_id": "123", "endpoint": "host:notaport"}`, + `{"account_id": "123", "endpoint": "host:8080:extra"}`, + `{"account_id": "123", "endpoint": "host:8080"}`, } diff --git a/adapters/rediads/rediads.go b/adapters/rediads/rediads.go index cfa60eacf6..bbf6a8e1dc 100644 --- a/adapters/rediads/rediads.go +++ b/adapters/rediads/rediads.go @@ -7,11 +7,12 @@ import ( "github.com/buger/jsonparser" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/urlutil" ) type adapter struct { @@ -99,6 +100,9 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte finalEndpoint := a.endpoint if endpoint != "" { + if !urlutil.IsSafeHost(endpoint) { + return nil, []error{&errortypes.BadInput{Message: "Invalid endpoint"}} + } parsedURL, _ := url.Parse(finalEndpoint) host := parsedURL.Host parts := strings.Split(host, ".") diff --git a/adapters/rediads/rediads_test.go b/adapters/rediads/rediads_test.go index b5e935b680..ec263d8324 100644 --- a/adapters/rediads/rediads_test.go +++ b/adapters/rediads/rediads_test.go @@ -3,9 +3,9 @@ package rediads 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/rediads/rediadstest/supplemental/invalid-endpoint.json b/adapters/rediads/rediadstest/supplemental/invalid-endpoint.json new file mode 100644 index 0000000000..5766b970d1 --- /dev/null +++ b/adapters/rediads/rediadstest/supplemental/invalid-endpoint.json @@ -0,0 +1,31 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "account_id": "123", + "endpoint": "evil.com/path?redirect=http://attacker.com#" + } + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "pub1" + } + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Invalid endpoint", + "comparison": "literal" + } + ] +} diff --git a/adapters/relevantdigital/params_test.go b/adapters/relevantdigital/params_test.go index 987dfd6e58..21aad12ff1 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -34,9 +34,32 @@ func TestInvalidParams(t *testing.T) { } var validParams = []string{ - `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId" : "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost" : "some-host" }`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "host"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "host.example.com"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "host.example.com:8080"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "host-example.test"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "Host.Example.com"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "localhost:3000"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "https://foo.relevant-digital.com"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "http://foo.relevant-digital.com"}`, } var invalidParams = []string{ - `{"accountId": 123, "placementId" : 123, "pbsHost" : ""}`, + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"accountId": 123, "placementId": 123, "pbsHost": ""}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "host", "useSourceBidderCode": "somethingInvalid"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "/path"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "//evil.com"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "host/path"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "host?query=1"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "host#fragment"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "user@host"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "host:notaport"}`, + `{"accountId": "5fcf49f83a64ba6602b5be7e", "placementId": "63b68275b4f35962c8eec9b1_5fcf49f83a64ba6602b5be9a", "pbsHost": "host:8080:extra"}`, } diff --git a/adapters/relevantdigital/relevantdigital.go b/adapters/relevantdigital/relevantdigital.go index 702dca6b27..9fa8174fea 100644 --- a/adapters/relevantdigital/relevantdigital.go +++ b/adapters/relevantdigital/relevantdigital.go @@ -10,12 +10,13 @@ import ( "github.com/buger/jsonparser" "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/urlutil" jsonpatch "gopkg.in/evanphx/json-patch.v5" ) @@ -114,6 +115,11 @@ func setTMax(prebidBidRequest *openrtb2.BidRequest, pbsBufferMs int) { func createBidRequest(prebidBidRequest *openrtb2.BidRequest, params []*openrtb_ext.ExtRelevantDigital) ([]byte, error) { bidRequestCopy := *prebidBidRequest + // Copy Imp slice so patchBidImpExt only mutates this outgoing request. + // MakeBids receives the same request and needs the original Imp[].Ext + // to read useSourceBidderCode from bidder params. + bidRequestCopy.Imp = make([]openrtb2.Imp, len(prebidBidRequest.Imp)) + copy(bidRequestCopy.Imp, prebidBidRequest.Imp) err := patchBidRequestExt(&bidRequestCopy, params[0].AccountId) if err != nil { @@ -177,6 +183,9 @@ func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtRelevantDigital) (stri params.Host = strings.ReplaceAll(params.Host, "http://", "") params.Host = strings.ReplaceAll(params.Host, "https://", "") params.Host = strings.ReplaceAll(params.Host, relevant_domain, "") + if !urlutil.IsSafeHost(params.Host) { + return "", &errortypes.BadInput{Message: "Invalid Host"} + } endpointParams := macros.EndpointTemplateParams{Host: params.Host} return macros.ResolveMacros(a.endpoint, endpointParams) @@ -292,6 +301,17 @@ func isSupportedMediaType(bidType openrtb_ext.BidType) error { return fmt.Errorf("bid type not supported %s", bidType) } +func useSourceBidderCode(request *openrtb2.BidRequest) bool { + if request == nil || len(request.Imp) == 0 { + return false + } + impExt, err := getImpressionExt(&request.Imp[0]) + if err != nil { + return false + } + return impExt.UseSourceBidderCode +} + func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { if adapters.IsResponseStatusCodeNoContent(responseData) { return nil, nil @@ -306,6 +326,8 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R return nil, []error{err} } + passSourceSeat := useSourceBidderCode(request) + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(response.SeatBid)) bidResponse.Currency = response.Cur var errs []error @@ -324,6 +346,9 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R Bid: &seatBid.Bid[i], BidType: bidType, } + if passSourceSeat { + b.Seat = openrtb_ext.BidderName(seatBid.Seat) + } bidResponse.Bids = append(bidResponse.Bids, b) } } diff --git a/adapters/relevantdigital/relevantdigital_test.go b/adapters/relevantdigital/relevantdigital_test.go index 31e6b370d8..8859a27d37 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/relevantdigital/relevantdigitaltest/supplemental/host-normalization.json b/adapters/relevantdigital/relevantdigitaltest/supplemental/host-normalization.json new file mode 100644 index 0000000000..2f320358e2 --- /dev/null +++ b/adapters/relevantdigital/relevantdigitaltest/supplemental/host-normalization.json @@ -0,0 +1,137 @@ +{ + "mockBidRequest": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "accountId": "620523ae7f4bbe1691bbb815", + "pbsHost": "https://fakeHost.relevant-digital.com", + "placementId": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com", + "publisher": { + "id": "1001", + "domain": "somepub.com" + } + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakeHost.relevant-digital.com/openrtb2/auction", + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com", + "publisher": { + "id": "1001", + "domain": "somepub.com" + } + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "ext": { + "prebid": { + "debug": false, + "storedrequest": { + "id": "620523ae7f4bbe1691bbb815" + } + }, + "relevant": { + "adapterType": "server", + "count": 1 + } + }, + "tmax": 750 + }, + "impIDs": ["div-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "seatbid": [ + { + "seat": "relevantdigital", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "div-1", + "price": 0.5, + "adm": "some-ad-markup", + "crid": "crid_10", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "div-1", + "price": 0.5, + "adm": "some-ad-markup", + "crid": "crid_10", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/relevantdigital/relevantdigitaltest/supplemental/invalid-host.json b/adapters/relevantdigital/relevantdigitaltest/supplemental/invalid-host.json new file mode 100644 index 0000000000..1a29f98435 --- /dev/null +++ b/adapters/relevantdigital/relevantdigitaltest/supplemental/invalid-host.json @@ -0,0 +1,31 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "testaccount", + "placementId": "testplacement", + "pbsHost": "evil.com/path?redirect=http://attacker.com#" + } + } + } + ], + "site": { + "page": "test.com" + } + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Invalid Host", + "comparison": "literal" + } + ] +} diff --git a/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCode.json b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCode.json new file mode 100644 index 0000000000..1b8e105dfe --- /dev/null +++ b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCode.json @@ -0,0 +1,131 @@ +{ + "mockBidRequest": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "accountId": "620523ae7f4bbe1691bbb815", + "pbsHost": "fakeHost", + "placementId": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817", + "useSourceBidderCode": true + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakeHost.relevant-digital.com/openrtb2/auction", + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "ext": { + "prebid": { + "debug": false, + "storedrequest": { + "id": "620523ae7f4bbe1691bbb815" + } + }, + "relevant": { + "adapterType": "server", + "count": 1 + } + }, + "tmax": 750 + }, + "impIDs": ["div-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "seatbid": [ + { + "seat": "pubmatic", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "div-1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "div-1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner", + "seat": "pubmatic" + } + ] + } + ] +} diff --git a/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabled.json b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabled.json new file mode 100644 index 0000000000..a8ab5a81c0 --- /dev/null +++ b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabled.json @@ -0,0 +1,129 @@ +{ + "mockBidRequest": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "accountId": "620523ae7f4bbe1691bbb815", + "pbsHost": "fakeHost", + "placementId": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakeHost.relevant-digital.com/openrtb2/auction", + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "ext": { + "prebid": { + "debug": false, + "storedrequest": { + "id": "620523ae7f4bbe1691bbb815" + } + }, + "relevant": { + "adapterType": "server", + "count": 1 + } + }, + "tmax": 750 + }, + "impIDs": ["div-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "seatbid": [ + { + "seat": "pubmatic", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "div-1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "div-1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabledMultipleSeatBids.json b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabledMultipleSeatBids.json new file mode 100644 index 0000000000..8040c2e039 --- /dev/null +++ b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabledMultipleSeatBids.json @@ -0,0 +1,157 @@ +{ + "mockBidRequest": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "accountId": "620523ae7f4bbe1691bbb815", + "pbsHost": "fakeHost", + "placementId": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakeHost.relevant-digital.com/openrtb2/auction", + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "ext": { + "prebid": { + "debug": false, + "storedrequest": { + "id": "620523ae7f4bbe1691bbb815" + } + }, + "relevant": { + "adapterType": "server", + "count": 1 + } + }, + "tmax": 750 + }, + "impIDs": ["div-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "seatbid": [ + { + "seat": "pubmatic", + "bid": [ + { + "id": "bid-1", + "impid": "div-1", + "price": 0.5, + "adm": "pubmatic-ad", + "crid": "crid_1", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + }, + { + "seat": "appnexus", + "bid": [ + { + "id": "bid-2", + "impid": "div-1", + "price": 0.8, + "adm": "appnexus-ad", + "crid": "crid_2", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "div-1", + "price": 0.5, + "adm": "pubmatic-ad", + "crid": "crid_1", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "bid-2", + "impid": "div-1", + "price": 0.8, + "adm": "appnexus-ad", + "crid": "crid_2", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeMultipleSeatBids.json b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeMultipleSeatBids.json new file mode 100644 index 0000000000..1a0b8e2aac --- /dev/null +++ b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeMultipleSeatBids.json @@ -0,0 +1,160 @@ +{ + "mockBidRequest": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "accountId": "620523ae7f4bbe1691bbb815", + "pbsHost": "fakeHost", + "placementId": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817", + "useSourceBidderCode": true + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakeHost.relevant-digital.com/openrtb2/auction", + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "ext": { + "prebid": { + "debug": false, + "storedrequest": { + "id": "620523ae7f4bbe1691bbb815" + } + }, + "relevant": { + "adapterType": "server", + "count": 1 + } + }, + "tmax": 750 + }, + "impIDs": ["div-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "seatbid": [ + { + "seat": "pubmatic", + "bid": [ + { + "id": "bid-1", + "impid": "div-1", + "price": 0.5, + "adm": "pubmatic-ad", + "crid": "crid_1", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + }, + { + "seat": "appnexus", + "bid": [ + { + "id": "bid-2", + "impid": "div-1", + "price": 0.8, + "adm": "appnexus-ad", + "crid": "crid_2", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "div-1", + "price": 0.5, + "adm": "pubmatic-ad", + "crid": "crid_1", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner", + "seat": "pubmatic" + }, + { + "bid": { + "id": "bid-2", + "impid": "div-1", + "price": 0.8, + "adm": "appnexus-ad", + "crid": "crid_2", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner", + "seat": "appnexus" + } + ] + } + ] +} diff --git a/adapters/resetdigital/params_test.go b/adapters/resetdigital/params_test.go index 4098b44493..f82b10855e 100644 --- a/adapters/resetdigital/params_test.go +++ b/adapters/resetdigital/params_test.go @@ -4,10 +4,9 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) -// TestValidParams tests valid parameter(s) declared in openrtb_ext/imp_resetdigital.go func TestValidParams(t *testing.T) { validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") if err != nil { @@ -21,7 +20,6 @@ func TestValidParams(t *testing.T) { } } -// TestValidParams tests invalid parameter(s) declared in openrtb_ext/imp_resetdigital.go func TestInvalidParams(t *testing.T) { validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") if err != nil { @@ -35,17 +33,13 @@ func TestInvalidParams(t *testing.T) { } } -// list of valid parameter(s) test cases var validParams = []string{ `{"placement_id":"1000"}`, `{"placement_id":"0"}`, `{"placement_id":"abc"}`, `{"placement_id":"123abc"}`, - `{}`, - `{"cp":"1000"}`, } -// list of invalid parameter(s) test cases var invalidParams = []string{ ``, `null`, @@ -55,4 +49,6 @@ var invalidParams = []string{ `[]`, `{"placement_id":}`, `{"placement_id":""}`, + `{"placement_id": 123}`, + `{"cp":"1000"}`, } diff --git a/adapters/resetdigital/resetdigital.go b/adapters/resetdigital/resetdigital.go index 2a619e7604..40050400ea 100644 --- a/adapters/resetdigital/resetdigital.go +++ b/adapters/resetdigital/resetdigital.go @@ -4,305 +4,231 @@ import ( "encoding/json" "fmt" "net/http" - "strconv" - "text/template" + "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/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "golang.org/x/text/currency" ) -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,omitempty"` - Video resetDigitalMediaType `json:"video,omitempty"` - Audio resetDigitalMediaType `json:"audio,omitempty"` -} -type resetDigitalMediaType struct { - Sizes [][]int64 `json:"sizes,omitempty"` - Mimes []string `json:"mimes,omitempty"` -} -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"` -} +const ( + contentTypeJSON = "application/json" + openRTBVersion = "2.6" + currencyUSD = "USD" + bidderSeat = "resetdigital" +) -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 +var baseHeaders = http.Header{ + "Content-Type": []string{contentTypeJSON}, + "Accept": []string{contentTypeJSON}, + "X-OpenRTB-Version": []string{openRTBVersion}, } -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 +type adapter struct { + endpoint string } -func addNonEmptyHeaders(headers *http.Header, headerValues map[string]string) { - for key, value := range headerValues { - if len(value) > 0 { - headers.Add(key, value) - } - } +func Builder(_ openrtb_ext.BidderName, cfg config.Adapter, _ config.Server) (adapters.Bidder, error) { + return &adapter{ + endpoint: cfg.Endpoint, + }, nil } -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 - } +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - requests = append(requests, &adapters.RequestData{ - Method: "POST", - Uri: a.endpointUri, - Body: requestBody, - Headers: getHeaders(requestData), - ImpIDs: []string{imp.ID}, - }) + if len(request.Imp) != 1 { + return nil, []error{&errortypes.BadInput{ + Message: "ResetDigital adapter supports only one impression per request", + }} } - 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 + imp := request.Imp[0] + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Error parsing bidderExt from imp.ext: %v", err), + }} } - rdImp := resetDigitalImp{ - BidID: requestData.ID, - ImpID: imp.ID, + var resetDigitalExt openrtb_ext.ImpExtResetDigital + if err := json.Unmarshal(bidderExt.Bidder, &resetDigitalExt); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Error parsing resetDigitalExt from bidderExt.bidder: %v", err), + }} + } + + reqCopy := openrtb2.BidRequest{ + ID: request.ID, + Source: request.Source, + TMax: request.TMax, + Test: request.Test, + Imp: []openrtb2.Imp{imp}, + Device: request.Device, + Site: request.Site, + App: request.App, + User: request.User, + Regs: request.Regs, + Ext: request.Ext, + AT: request.AT, + BAdv: request.BAdv, + BCat: request.BCat, + BSeat: request.BSeat, + WLang: request.WLang, + WSeat: request.WSeat, + } + + if imp.TagID == "" { + reqCopy.Imp[0].TagID = resetDigitalExt.PlacementID + } + + reqCopy.Cur = validateAndFilterCurrencies(request.Cur) + + reqBody, err := json.Marshal(&reqCopy) + if err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Error marshalling OpenRTB request: %v", err), + }} } - 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 { - rdImp.MediaTypes.Banner.Sizes = append(rdImp.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 { - rdImp.MediaTypes.Video.Sizes = append(rdImp.MediaTypes.Video.Sizes, []int64{tempW, tempH}) - } - if imp.Video.MIMEs != nil { - rdImp.MediaTypes.Video.Mimes = append(rdImp.MediaTypes.Video.Mimes, imp.Video.MIMEs...) - } - } - if bidType == openrtb_ext.BidTypeAudio && imp.Audio != nil && imp.Audio.MIMEs != nil { - rdImp.MediaTypes.Audio.Mimes = append(rdImp.MediaTypes.Audio.Mimes, imp.Audio.MIMEs...) - } + uri := fmt.Sprintf("%s?pid=%s", a.endpoint, resetDigitalExt.PlacementID) - var bidderExt adapters.ExtImpBidder - var resetDigitalExt openrtb_ext.ImpExtResetDigital + reqHeaders := baseHeaders.Clone() - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { - return resetDigitalRequest{}, err - } - if err := json.Unmarshal(bidderExt.Bidder, &resetDigitalExt); err != nil { - return resetDigitalRequest{}, err + reqs := []*adapters.RequestData{ + { + Method: http.MethodPost, + Uri: uri, + Body: reqBody, + Headers: reqHeaders, + ImpIDs: []string{imp.ID}, + }, } - rdImp.ZoneID.PlacementID = resetDigitalExt.PlacementID - - reqData.Imps = append(reqData.Imps, rdImp) - return reqData, nil + return reqs, nil } -func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { - if adapters.IsResponseStatusCodeNoContent(responseData) { +func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if responseData.StatusCode == http.StatusNoContent { return nil, nil } - if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { - return nil, []error{err} + if responseData.StatusCode >= http.StatusBadRequest && responseData.StatusCode < http.StatusInternalServerError { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", responseData.StatusCode), + }} } - var response resetDigitalBidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { - return nil, []error{err} + if responseData.StatusCode != http.StatusOK { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", responseData.StatusCode), + }} } - if len(response.Bids) != 1 { - return nil, []error{fmt.Errorf("expected exactly one bid in the response, but got %d", len(response.Bids))} + var bidResp openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &bidResp); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("Bad server response: %s", err), + }} } - resetDigitalBid := &response.Bids[0] - - requestImp, found := findRequestImpByID(request.Imp, resetDigitalBid.ImpID) - if !found { - return nil, []error{fmt.Errorf("no matching impression found for ImpID %s", resetDigitalBid.ImpID)} + if len(bidResp.SeatBid) == 0 { + return nil, nil } - bid, err := getBidFromResponse(resetDigitalBid) - if err != nil { - return nil, []error{err} + return parseBidResponse(request, &bidResp) +} + +func parseBidResponse(request *openrtb2.BidRequest, bidResp *openrtb2.BidResponse) (*adapters.BidderResponse, []error) { + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid)) + var errs []error + + if bidResp.Cur != "" { + bidResponse.Currency = bidResp.Cur + } else { + cur := validateAndFilterCurrencies(request.Cur) + bidResponse.Currency = cur[0] } - bidType := GetMediaTypeForImp(requestImp) + for _, seatBid := range bidResp.SeatBid { + for i := range seatBid.Bid { + if seatBid.Bid[i].Price <= 0 { + errs = append(errs, &errortypes.Warning{ + Message: fmt.Sprintf("price %f <= 0 filtered out", seatBid.Bid[i].Price), + }) + continue + } - bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) - bidResponse.Currency = "USD" // Default currency - bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ - Bid: bid, - BidType: bidType, - Seat: openrtb_ext.BidderName(resetDigitalBid.Seat), - }) + bidType, err := getBidType(seatBid.Bid[i], request) + if err != nil { + errs = append(errs, err) + continue + } - return bidResponse, nil -} + seat := openrtb_ext.BidderName(bidderSeat) + if seatBid.Seat != "" { + seat = openrtb_ext.BidderName(seatBid.Seat) + } -// findRequestImpByID searches for an impression by its ID in the list of impressions -func findRequestImpByID(imps []openrtb2.Imp, impID string) (openrtb2.Imp, bool) { - for _, imp := range imps { - if imp.ID == impID { - return imp, true + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + Seat: seat, + }) } } - return openrtb2.Imp{}, false -} - -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, - } + return bidResponse, errs +} - w, err := strconv.ParseInt(bidResponse.W, 10, 64) - if err != nil { - return nil, err +func getBidType(bid openrtb2.Bid, request *openrtb2.BidRequest) (openrtb_ext.BidType, error) { + if bid.MType > 0 { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + } } - bid.W = w - - h, err := strconv.ParseInt(bidResponse.H, 10, 64) - if err != nil { - return nil, err + if request.Imp[0].ID != bid.ImpID { + return "", fmt.Errorf("no matching impression found for ImpID: %s", bid.ImpID) } - bid.H = h - return bid, nil + return getMediaType(request.Imp[0]), 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 +func validateAndFilterCurrencies(currencies []string) []string { + valid := make([]string, 0, len(currencies)) + for _, s := range currencies { + s = strings.TrimSpace(s) + if s == "" { + continue + } + s = strings.ToUpper(s) + if u, err := currency.ParseISO(s); err == nil { + valid = append(valid, u.String()) + } } - - return "", fmt.Errorf("failed to find matching imp for bid %s", imp.ID) + if len(valid) == 0 { + return []string{currencyUSD} + } + return valid } -func GetMediaTypeForImp(reqImp openrtb2.Imp) openrtb_ext.BidType { - - if reqImp.Video != nil { +func getMediaType(imp openrtb2.Imp) openrtb_ext.BidType { + switch { + case imp.Video != nil: return openrtb_ext.BidTypeVideo - } - if reqImp.Audio != nil { + case imp.Audio != nil: return openrtb_ext.BidTypeAudio + case imp.Native != nil: + return openrtb_ext.BidTypeNative + default: + return openrtb_ext.BidTypeBanner } - return openrtb_ext.BidTypeBanner } diff --git a/adapters/resetdigital/resetdigital_test.go b/adapters/resetdigital/resetdigital_test.go index 9efba33f30..dd33c8bdeb 100644 --- a/adapters/resetdigital/resetdigital_test.go +++ b/adapters/resetdigital/resetdigital_test.go @@ -1,17 +1,23 @@ package resetdigital import ( + "encoding/json" + "net/http" "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/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" ) 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"}) + Endpoint: "https://example.com", + }, config.Server{}) if buildErr != nil { t.Fatalf("Builder returned unexpected error %v", buildErr) @@ -19,3 +25,727 @@ func TestJsonSamples(t *testing.T) { adapterstest.RunJSONBidderTest(t, "resetdigitaltest", bidder) } + +func TestValidateAndFilterCurrencies(t *testing.T) { + tests := []struct { + name string + input []string + expected []string + }{ + { + name: "empty array", + input: []string{}, + expected: []string{"USD"}, + }, + { + name: "nil array", + input: nil, + expected: []string{"USD"}, + }, + { + name: "single empty string", + input: []string{""}, + expected: []string{"USD"}, + }, + { + name: "multiple empty strings", + input: []string{"", ""}, + expected: []string{"USD"}, + }, + { + name: "whitespace only strings", + input: []string{" ", "\t", "\n"}, + expected: []string{"USD"}, + }, + { + name: "single valid currency", + input: []string{"EUR"}, + expected: []string{"EUR"}, + }, + { + name: "multiple valid currencies", + input: []string{"USD", "EUR", "GBP"}, + expected: []string{"USD", "EUR", "GBP"}, + }, + { + name: "single invalid currency", + input: []string{"INVALID"}, + expected: []string{"USD"}, + }, + { + name: "mixed valid and invalid currencies", + input: []string{"USD", "INVALID", "EUR"}, + expected: []string{"USD", "EUR"}, + }, + { + name: "currencies with whitespace", + input: []string{" USD ", "\tEUR\t", " GBP\n"}, + expected: []string{"USD", "EUR", "GBP"}, + }, + { + name: "lowercase currencies", + input: []string{"usd", "eur"}, + expected: []string{"USD", "EUR"}, + }, + { + name: "mixed case currencies", + input: []string{"Usd", "EUR", "gbp"}, + expected: []string{"USD", "EUR", "GBP"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := validateAndFilterCurrencies(tt.input) + assert.Equal(t, tt.expected, result) + }) + } +} + +func TestGetMediaType(t *testing.T) { + tests := []struct { + name string + imp openrtb2.Imp + expected openrtb_ext.BidType + }{ + { + name: "Banner type", + imp: openrtb2.Imp{ + Banner: &openrtb2.Banner{}, + }, + expected: openrtb_ext.BidTypeBanner, + }, + { + name: "Video type", + imp: openrtb2.Imp{ + Video: &openrtb2.Video{}, + }, + expected: openrtb_ext.BidTypeVideo, + }, + { + name: "Audio type", + imp: openrtb2.Imp{ + Audio: &openrtb2.Audio{}, + }, + expected: openrtb_ext.BidTypeAudio, + }, + { + name: "Native type", + imp: openrtb2.Imp{ + Native: &openrtb2.Native{}, + }, + expected: openrtb_ext.BidTypeNative, + }, + { + name: "Multiple media types - prioritize video", + imp: openrtb2.Imp{ + Banner: &openrtb2.Banner{}, + Video: &openrtb2.Video{}, + }, + expected: openrtb_ext.BidTypeVideo, + }, + { + name: "Multiple media types - prioritize audio over banner", + imp: openrtb2.Imp{ + Banner: &openrtb2.Banner{}, + Audio: &openrtb2.Audio{}, + }, + expected: openrtb_ext.BidTypeAudio, + }, + { + name: "Multiple media types - prioritize native over banner", + imp: openrtb2.Imp{ + Banner: &openrtb2.Banner{}, + Native: &openrtb2.Native{}, + }, + expected: openrtb_ext.BidTypeNative, + }, + { + name: "No media type defaults to banner", + imp: openrtb2.Imp{}, + expected: openrtb_ext.BidTypeBanner, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := getMediaType(test.imp) + assert.Equal(t, test.expected, result) + }) + } +} + +func TestGetBidType(t *testing.T) { + tests := []struct { + name string + bid openrtb2.Bid + request *openrtb2.BidRequest + expected openrtb_ext.BidType + hasError bool + }{ + { + name: "Banner MType", + bid: openrtb2.Bid{ + MType: openrtb2.MarkupBanner, + }, + request: &openrtb2.BidRequest{}, + expected: openrtb_ext.BidTypeBanner, + hasError: false, + }, + { + name: "Video MType", + bid: openrtb2.Bid{ + MType: openrtb2.MarkupVideo, + }, + request: &openrtb2.BidRequest{}, + expected: openrtb_ext.BidTypeVideo, + hasError: false, + }, + { + name: "Audio MType", + bid: openrtb2.Bid{ + MType: openrtb2.MarkupAudio, + }, + request: &openrtb2.BidRequest{}, + expected: openrtb_ext.BidTypeAudio, + hasError: false, + }, + { + name: "Native MType", + bid: openrtb2.Bid{ + MType: openrtb2.MarkupNative, + }, + request: &openrtb2.BidRequest{}, + expected: openrtb_ext.BidTypeNative, + hasError: false, + }, + { + name: "No MType, lookup impression - banner", + bid: openrtb2.Bid{ + ImpID: "imp-1", + }, + request: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp-1", + Banner: &openrtb2.Banner{}, + }, + }, + }, + expected: openrtb_ext.BidTypeBanner, + hasError: false, + }, + { + name: "No MType, lookup impression - video", + bid: openrtb2.Bid{ + ImpID: "imp-1", + }, + request: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp-1", + Video: &openrtb2.Video{}, + }, + }, + }, + expected: openrtb_ext.BidTypeVideo, + hasError: false, + }, + { + name: "No matching impression", + bid: openrtb2.Bid{ + ImpID: "imp-not-found", + }, + request: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp-1", + Banner: &openrtb2.Banner{}, + }, + }, + }, + expected: "", + hasError: true, + }, + { + name: "Unknown MType falls back to impression lookup", + bid: openrtb2.Bid{ + ImpID: "imp-1", + MType: openrtb2.MarkupType(99), + }, + request: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp-1", + Banner: &openrtb2.Banner{}, + }, + }, + }, + expected: openrtb_ext.BidTypeBanner, + hasError: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + bidType, err := getBidType(test.bid, test.request) + + if test.hasError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, test.expected, bidType) + } + }) + } +} + +func TestMakeBidsErrorCases(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderResetDigital, config.Adapter{ + Endpoint: "https://example.com", + }, config.Server{}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + tests := []struct { + name string + responseData *adapters.ResponseData + expectNil bool + expectErrs int + errType interface{} + }{ + { + name: "Status 204 No Content", + responseData: &adapters.ResponseData{ + StatusCode: http.StatusNoContent, + }, + expectNil: true, + expectErrs: 0, + }, + { + name: "Status 400 Bad Request", + responseData: &adapters.ResponseData{ + StatusCode: http.StatusBadRequest, + Body: []byte(`{"error": "Bad Request"}`), + }, + expectNil: true, + expectErrs: 1, + errType: &errortypes.BadInput{}, + }, + { + name: "Status 500 Internal Server Error", + responseData: &adapters.ResponseData{ + StatusCode: http.StatusInternalServerError, + Body: []byte(`{"error": "Internal Server Error"}`), + }, + expectNil: true, + expectErrs: 1, + errType: &errortypes.BadServerResponse{}, + }, + { + name: "Invalid JSON response", + responseData: &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{invalid json`), + }, + expectNil: true, + expectErrs: 1, + errType: &errortypes.BadServerResponse{}, + }, + { + name: "Empty seatbid array", + responseData: &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{"id": "test", "seatbid": []}`), + }, + expectNil: true, + expectErrs: 0, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + request := &openrtb2.BidRequest{} + bidResponse, errs := bidder.MakeBids(request, &adapters.RequestData{}, test.responseData) + + if test.expectNil { + assert.Nil(t, bidResponse) + } else { + assert.NotNil(t, bidResponse) + } + + assert.Len(t, errs, test.expectErrs) + + if test.expectErrs > 0 && test.errType != nil { + assert.IsType(t, test.errType, errs[0]) + } + }) + } +} + +func TestMakeRequestsErrorCases(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderResetDigital, config.Adapter{ + Endpoint: "https://example.com", + }, config.Server{}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + tests := []struct { + name string + request *openrtb2.BidRequest + expectNil bool + expectErrs int + errType interface{} + }{ + { + name: "Multiple impressions", + request: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp1", Ext: json.RawMessage(`{"bidder": {"placement_id": "test"}}`)}, + {ID: "imp2", Ext: json.RawMessage(`{"bidder": {"placement_id": "test"}}`)}, + }, + }, + expectNil: true, + expectErrs: 1, + errType: &errortypes.BadInput{}, + }, + { + name: "Malformed imp.ext", + request: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "test-imp-id", + Ext: json.RawMessage(`{invalid json`), + }, + }, + }, + expectNil: true, + expectErrs: 1, + errType: &errortypes.BadInput{}, + }, + { + name: "Malformed bidder params", + request: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "test-imp-id", + Ext: json.RawMessage(`{"bidder": {invalid json}`), + }, + }, + }, + expectNil: true, + expectErrs: 1, + errType: &errortypes.BadInput{}, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + reqs, errs := bidder.MakeRequests(test.request, &adapters.ExtraRequestInfo{}) + + if test.expectNil { + assert.Nil(t, reqs) + } else { + assert.NotNil(t, reqs) + } + + assert.Len(t, errs, test.expectErrs) + + if test.expectErrs > 0 && test.errType != nil { + assert.IsType(t, test.errType, errs[0]) + } + }) + } +} + +func TestParseBidResponseEdgeCases(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderResetDigital, config.Adapter{ + Endpoint: "https://example.com", + }, config.Server{}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + tests := []struct { + name string + request *openrtb2.BidRequest + responseData *adapters.ResponseData + expectBids int + expectErrs int + }{ + { + name: "Bid with zero price filtered out", + request: &openrtb2.BidRequest{ + ID: "test-request-id", + Imp: []openrtb2.Imp{ + {ID: "test-imp-id", Banner: &openrtb2.Banner{}}, + }, + }, + responseData: &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{ + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.0, + "adm": "
test ad
" + } + ] + } + ], + "cur": "USD" + }`), + }, + expectBids: 0, + expectErrs: 1, + }, + { + name: "Bid with negative price filtered out", + request: &openrtb2.BidRequest{ + ID: "test-request-id", + Imp: []openrtb2.Imp{ + {ID: "test-imp-id", Banner: &openrtb2.Banner{}}, + }, + }, + responseData: &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{ + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": -1.5, + "adm": "
test ad
" + } + ] + } + ], + "cur": "USD" + }`), + }, + expectBids: 0, + expectErrs: 1, + }, + { + name: "Currency fallback to request currency", + request: &openrtb2.BidRequest{ + ID: "test-request-id", + Cur: []string{"EUR"}, + Imp: []openrtb2.Imp{ + {ID: "test-imp-id", Banner: &openrtb2.Banner{}}, + }, + }, + responseData: &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{ + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
test ad
" + } + ] + } + ] + }`), + }, + expectBids: 1, + expectErrs: 0, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + bidResponse, errs := bidder.MakeBids(test.request, &adapters.RequestData{}, test.responseData) + + if test.expectBids > 0 { + assert.NotNil(t, bidResponse) + assert.Len(t, bidResponse.Bids, test.expectBids) + } + + assert.Len(t, errs, test.expectErrs) + }) + } +} + +func TestSchainPassthrough(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderResetDigital, config.Adapter{ + Endpoint: "https://example.com", + }, config.Server{}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + tests := []struct { + name string + request *openrtb2.BidRequest + expectSchain bool + expectedSchain *openrtb2.SupplyChain + }{ + { + name: "Request with schain should pass it through", + request: &openrtb2.BidRequest{ + ID: "test-request-id", + Source: &openrtb2.Source{ + TID: "test-transaction-id", + SChain: &openrtb2.SupplyChain{ + Complete: 1, + Ver: "1.0", + Nodes: []openrtb2.SupplyChainNode{ + { + ASI: "example.com", + SID: "12345", + HP: openrtb2.Int8Ptr(1), + RID: "request-id-123", + }, + }, + }, + }, + Imp: []openrtb2.Imp{ + { + ID: "test-imp-id", + Ext: json.RawMessage(`{"bidder": {"placement_id": "test-placement"}}`), + }, + }, + }, + expectSchain: true, + expectedSchain: &openrtb2.SupplyChain{ + Complete: 1, + Ver: "1.0", + Nodes: []openrtb2.SupplyChainNode{ + { + ASI: "example.com", + SID: "12345", + HP: openrtb2.Int8Ptr(1), + RID: "request-id-123", + }, + }, + }, + }, + { + name: "Request without schain should not include it", + request: &openrtb2.BidRequest{ + ID: "test-request-id", + Source: &openrtb2.Source{ + TID: "test-transaction-id", + }, + Imp: []openrtb2.Imp{ + { + ID: "test-imp-id", + Ext: json.RawMessage(`{"bidder": {"placement_id": "test-placement"}}`), + }, + }, + }, + expectSchain: false, + expectedSchain: nil, + }, + { + name: "Request without source should not include schain", + request: &openrtb2.BidRequest{ + ID: "test-request-id", + Imp: []openrtb2.Imp{ + { + ID: "test-imp-id", + Ext: json.RawMessage(`{"bidder": {"placement_id": "test-placement"}}`), + }, + }, + }, + expectSchain: false, + expectedSchain: nil, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + reqs, errs := bidder.MakeRequests(test.request, &adapters.ExtraRequestInfo{}) + + assert.Empty(t, errs) + assert.Len(t, reqs, 1) + + var sentRequest openrtb2.BidRequest + err := json.Unmarshal(reqs[0].Body, &sentRequest) + assert.NoError(t, err) + + if test.expectSchain { + assert.NotNil(t, sentRequest.Source) + assert.NotNil(t, sentRequest.Source.SChain) + assert.Equal(t, test.expectedSchain.Complete, sentRequest.Source.SChain.Complete) + assert.Equal(t, test.expectedSchain.Ver, sentRequest.Source.SChain.Ver) + assert.Len(t, sentRequest.Source.SChain.Nodes, len(test.expectedSchain.Nodes)) + + if len(sentRequest.Source.SChain.Nodes) > 0 { + assert.Equal(t, test.expectedSchain.Nodes[0].ASI, sentRequest.Source.SChain.Nodes[0].ASI) + assert.Equal(t, test.expectedSchain.Nodes[0].SID, sentRequest.Source.SChain.Nodes[0].SID) + assert.Equal(t, test.expectedSchain.Nodes[0].HP, sentRequest.Source.SChain.Nodes[0].HP) + assert.Equal(t, test.expectedSchain.Nodes[0].RID, sentRequest.Source.SChain.Nodes[0].RID) + } + } else { + if sentRequest.Source != nil { + assert.Nil(t, sentRequest.Source.SChain) + } + } + }) + } +} + +func TestSourceFieldsPassthrough(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderResetDigital, config.Adapter{ + Endpoint: "https://example.com", + }, config.Server{}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + request := &openrtb2.BidRequest{ + ID: "test-request-id", + Source: &openrtb2.Source{ + TID: "test-transaction-id", + FD: openrtb2.Int8Ptr(1), + Ext: json.RawMessage(`{"custom": "data"}`), + }, + Imp: []openrtb2.Imp{ + { + ID: "test-imp-id", + Ext: json.RawMessage(`{"bidder": {"placement_id": "test-placement"}}`), + }, + }, + } + + reqs, errs := bidder.MakeRequests(request, &adapters.ExtraRequestInfo{}) + + assert.Empty(t, errs) + assert.Len(t, reqs, 1) + + var sentRequest openrtb2.BidRequest + err := json.Unmarshal(reqs[0].Body, &sentRequest) + assert.NoError(t, err) + + assert.NotNil(t, sentRequest.Source) + assert.Equal(t, "test-transaction-id", sentRequest.Source.TID) + assert.Equal(t, openrtb2.Int8Ptr(1), sentRequest.Source.FD) + + var expectedExt, actualExt map[string]interface{} + err = json.Unmarshal([]byte(`{"custom": "data"}`), &expectedExt) + assert.NoError(t, err) + err = json.Unmarshal(sentRequest.Source.Ext, &actualExt) + assert.NoError(t, err) + assert.Equal(t, expectedExt, actualExt) +} diff --git a/adapters/resetdigital/resetdigitaltest/exemplary/simple-audio.json b/adapters/resetdigital/resetdigitaltest/exemplary/simple-audio.json index d032b4c6f3..38a44e8cf2 100644 --- a/adapters/resetdigital/resetdigitaltest/exemplary/simple-audio.json +++ b/adapters/resetdigital/resetdigitaltest/exemplary/simple-audio.json @@ -1,155 +1,82 @@ { "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": "" - }, + "id": "test-audio-request-id", "imp": [ { - "id": "001", - "bidfloor": 1.429, - "tagid": "667", - "secure": 1, + "id": "test-audio-imp-id", "audio": { - "protocols": [ - 2, - 3, - 5, - 6 - ], - "mimes": [ - "audio/mp4", - "audio/mp3" - ], - "api": [], - "minduration": 15, - "maxduration": 60, - "startdelay": -1 + "mimes": ["audio/mpeg"], + "minduration": 5, + "maxduration": 30 }, "ext": { "bidder": { - "placement_id": "placement-id-1" + "placement_id": "test-audio-placement" } } } ], "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 + "page": "https://example.com/audio", + "domain": "example.com" + } }, "httpCalls": [ { "expectedRequest": { - "method": "POST", + "uri": "https://example.com?pid=test-audio-placement", "body": { - "imps": [ + "id": "test-audio-request-id", + "imp": [ { - "bid_id": "12345", - "ext": { - "gpid": "" + "id": "test-audio-imp-id", + "audio": { + "mimes": ["audio/mpeg"], + "minduration": 5, + "maxduration": 30 }, - "imp_id": "001", - "media_types": { - "banner": {}, - "video": {}, - "audio": { - "mimes": [ - "audio/mp4", - "audio/mp3" - ] + "tagid": "test-audio-placement", + "ext": { + "bidder": { + "placement_id": "test-audio-placement" } - }, - "zone_id": { - "placementId": "placement-id-1" } } ], "site": { - "domain": "https://test.com", - "referrer": "https://test.com/2016/06/12" - } + "page": "https://example.com/audio", + "domain": "example.com" + }, + "cur": ["USD"] + }, + "headers": { + "Content-Type": ["application/json"], + "Accept": ["application/json"], + "X-OpenRTB-Version": ["2.6"] }, - "impIDs": [ - "001" - ] + "impIDs": ["test-audio-imp-id"] }, "mockResponse": { "status": 200, "body": { - "bids": [ + "id": "test-audio-request-id", + "seatbid": [ { - "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": "test markup" + "bid": [ + { + "id": "test-audio-bid-id", + "impid": "test-audio-imp-id", + "price": 4.2, + "adm": "", + "crid": "test-audio-creative-id", + "adomain": ["example.com"], + "mtype": 3 + } + ], + "seat": "resetdigital" } - ] + ], + "cur": "USD" } } } @@ -160,12 +87,13 @@ "bids": [ { "bid": { - "adm": "test markup", - "cid": "1000048-1002918", - "crid": "1003893", - "id": "01", - "impid": "001", - "price": 9.11 + "id": "test-audio-bid-id", + "impid": "test-audio-imp-id", + "price": 4.2, + "adm": "", + "crid": "test-audio-creative-id", + "adomain": ["example.com"], + "mtype": 3 }, "type": "audio", "seat": "resetdigital" @@ -173,4 +101,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/resetdigital/resetdigitaltest/exemplary/simple-banner.json b/adapters/resetdigital/resetdigitaltest/exemplary/simple-banner.json index 2a0fcacd55..22a0584e9c 100644 --- a/adapters/resetdigital/resetdigitaltest/exemplary/simple-banner.json +++ b/adapters/resetdigital/resetdigitaltest/exemplary/simple-banner.json @@ -1,101 +1,120 @@ { "mockBidRequest": { - "id": "12345", - "imp": [{ - "id": "001", - "banner": { - "h": 300, - "w": 250 - }, - "ext": { - "bidder": { - "placement_id": "placement-id-1" + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placement_id": "test-placement" + } } } - }], - "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 + "site": { + "page": "https://example.com", + "domain": "example.com" + } }, - "httpCalls": [{ - "expectedRequest": { - "method": "POST", - "body": { - "imps": [{ - "bid_id": "12345", - "ext": { - "gpid": "" - }, - "imp_id": "001", - "media_types": { - "banner": { - "sizes": [ - [ - 250, - 300 + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-placement", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } ] - ] - }, - "audio": {}, - "video": {} + }, + "tagid": "test-placement", + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com", + "domain": "example.com" }, - "zone_id": { - "placementId": "placement-id-1" - } - }], - "site": { - "domain": "https://test.com", - "referrer": "https://test.com/2016/06/12" - } + "cur": [ + "USD" + ] + }, + "headers": { + "Content-Type": [ + "application/json" + ], + "Accept": [ + "application/json" + ], + "X-OpenRTB-Version": [ + "2.6" + ] + }, + "impIDs": ["test-imp-id"] }, - "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": "test markup" - }] + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.14, + "adm": "
test ad
", + "crid": "test-creative-id", + "w": 300, + "h": 250, + "adomain": ["example.com"] + } + ], + "seat": "resetdigital" + } + ], + "cur": "USD" + } } } - }], - - "expectedBidResponses": [{ - "currency": "USD", - "bids": [{ - "bid": { - "adm": "test markup", - "cid": "1002088", - "crid": "1000763-1002088", - "id": "01", - "impid": "001", - "price": 1.00, - "w": 300, - "h": 250 - }, - "type": "banner", - "seat": "resetdigital" - }] - }] + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.14, + "adm": "
test ad
", + "crid": "test-creative-id", + "w": 300, + "h": 250, + "adomain": ["example.com"] + }, + "type": "banner", + "seat": "resetdigital" + } + ] + } + ] } diff --git a/adapters/resetdigital/resetdigitaltest/exemplary/simple-video.json b/adapters/resetdigital/resetdigitaltest/exemplary/simple-video.json deleted file mode 100644 index ce4e1916fd..0000000000 --- a/adapters/resetdigital/resetdigitaltest/exemplary/simple-video.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "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": {}, - "video": { - "sizes": [ - [ - 900, - 250 - ] - ], - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "audio": {} - }, - "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": "test markup" - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "adm": "test markup", - "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/intertech/intertechtest/supplemental/invalid-bidder.json b/adapters/resetdigital/resetdigitaltest/supplemental/bad-ext-bidder.json similarity index 60% rename from adapters/intertech/intertechtest/supplemental/invalid-bidder.json rename to adapters/resetdigital/resetdigitaltest/supplemental/bad-ext-bidder.json index 0f530a0e68..2e538cb024 100644 --- a/adapters/intertech/intertechtest/supplemental/invalid-bidder.json +++ b/adapters/resetdigital/resetdigitaltest/supplemental/bad-ext-bidder.json @@ -1,6 +1,6 @@ { "mockBidRequest": { - "id": "test-req-id", + "id": "test-request-id", "imp": [ { "id": "test-imp-id", @@ -13,16 +13,18 @@ ] }, "ext": { - "bidder": "badBidder" + "prebid": 1 } } - ] + ], + "site": { + "page": "https://example.com" + } }, - "expectedMakeRequestsErrors": [ { - "value": "imp #test-imp-id: unable to parse intertech ext: expect { or n, but found \"", - "comparison": "literal" + "value": "Error parsing bidderExt from imp.ext:", + "comparison": "regex" } ] } diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/bad-ext-resetdigital.json b/adapters/resetdigital/resetdigitaltest/supplemental/bad-ext-resetdigital.json new file mode 100644 index 0000000000..428bbdee22 --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/bad-ext-resetdigital.json @@ -0,0 +1,32 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placement_id": 123 + } + } + } + ], + "site": { + "page": "https://example.com" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Error parsing resetDigitalExt from bidderExt.bidder:", + "comparison": "regex" + } + ] +} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/bad-response-body.json b/adapters/resetdigital/resetdigitaltest/supplemental/bad-response-body.json new file mode 100644 index 0000000000..c4aa6c727b --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/bad-response-body.json @@ -0,0 +1,74 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-placement", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "test-placement", + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + }, + "cur": [ + "USD" + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": 123 + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad server response:", + "comparison": "regex" + } + ] +} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/currency-fallback.json b/adapters/resetdigital/resetdigitaltest/supplemental/currency-fallback.json new file mode 100644 index 0000000000..c4757d6588 --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/currency-fallback.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + }, + "cur": ["EUR"] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-placement", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "test-placement", + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + }, + "cur": [ + "EUR" + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
test ad
", + "crid": "test-creative-id", + "w": 300, + "h": 250 + } + ], + "seat": "resetdigital" + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
test ad
", + "crid": "test-creative-id", + "w": 300, + "h": 250 + }, + "type": "banner", + "seat": "resetdigital" + } + ] + } + ] +} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/empty-response.json b/adapters/resetdigital/resetdigitaltest/supplemental/empty-response.json new file mode 100644 index 0000000000..f83460632f --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/empty-response.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-empty-request-id", + "imp": [ + { + "id": "test-empty-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placement_id": "test-no-bids-placement" + } + } + } + ], + "site": { + "page": "https://example.com/empty", + "domain": "example.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-no-bids-placement", + "body": { + "id": "test-empty-request-id", + "imp": [ + { + "id": "test-empty-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "test-no-bids-placement", + "ext": { + "bidder": { + "placement_id": "test-no-bids-placement" + } + } + } + ], + "site": { + "page": "https://example.com/empty", + "domain": "example.com" + }, + "cur": [ + "USD" + ] + }, + "headers": { + "Content-Type": [ + "application/json" + ], + "Accept": [ + "application/json" + ], + "X-OpenRTB-Version": [ + "2.6" + ] + }, + "impIDs": ["test-empty-imp-id"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/imp-id-mismatch.json b/adapters/resetdigital/resetdigitaltest/supplemental/imp-id-mismatch.json deleted file mode 100644 index a763e88561..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/imp-id-mismatch.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "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": { - "sizes": [ - [ - 250, - 300 - ] - ] - }, - "video": {}, - "audio": {} - }, - "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": "999", - "cpm": 1.00, - "cid": "1002088", - "crid": "1000763-1002088", - "adid": "1002088", - "w": "300", - "h": "250", - "seat": "resetdigital", - "html": "test markup" - }] - } - } - }], - - "expectedMakeBidsErrors": [ - { - "value": "no matching impression found for ImpID 999", - "comparison": "literal" - } - ] - } - \ No newline at end of file diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/invalid-bid-height.json b/adapters/resetdigital/resetdigitaltest/supplemental/invalid-bid-height.json deleted file mode 100644 index d1c40ffaba..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/invalid-bid-height.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "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": { - "sizes": [ - [ - 250, - 300 - ] - ] - }, - "video": {}, - "audio": {} - }, - "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": "123456789012345678901234567890123456789012345678901234567890", - "seat": "resetdigital", - "html": "test markup" - }] - } - } - }], - - "expectedMakeBidsErrors": [ - { - "value": "strconv.ParseInt: parsing \"123456789012345678901234567890123456789012345678901234567890\": value out of range", - "comparison": "literal" - } - ], - "expectedBidResponses": [] -} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/invalid-bid-width.json b/adapters/resetdigital/resetdigitaltest/supplemental/invalid-bid-width.json deleted file mode 100644 index 8c118bfecd..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/invalid-bid-width.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "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": { - "sizes": [ - [ - 250, - 300 - ] - ] - }, - "video": {}, - "audio": {} - }, - "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": "123456789012345678901234567890123456789012345678901234567890", - "h": "250", - "seat": "resetdigital", - "html": "test markup" - }] - } - } - }], - - "expectedMakeBidsErrors": [ - { - "value": "strconv.ParseInt: parsing \"123456789012345678901234567890123456789012345678901234567890\": value out of range", - "comparison": "literal" - } - ], - "expectedBidResponses": [] -} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/invalid-cur.json b/adapters/resetdigital/resetdigitaltest/supplemental/invalid-cur.json deleted file mode 100644 index 3dcf7a7656..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/invalid-cur.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "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": { - "sizes": [ - [ - 250, - 300 - ] - ] - }, - "video": {}, - "audio": {} - }, - "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-device.json b/adapters/resetdigital/resetdigitaltest/supplemental/invalid-device.json deleted file mode 100644 index 7b0fc8c264..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/invalid-device.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "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": { - "sizes": [ - [ - 250, - 300 - ] - ] - }, - "video": {}, - "audio": {} - }, - "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 deleted file mode 100644 index 0c24e666b9..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/invalid-media-def.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "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 deleted file mode 100644 index 14959b36d1..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/invalid-placement-id.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "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 deleted file mode 100644 index 4e1f43d13f..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/invalid-video-dim.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "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": {}, - "video": { - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "audio": {} - }, - "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/malformed-response.json b/adapters/resetdigital/resetdigitaltest/supplemental/malformed-response.json deleted file mode 100644 index 4a063d0843..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/malformed-response.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "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": { - "sizes": [ - [ - 250, - 300 - ] - ] - }, - "video": {}, - "audio": {} - }, - "zone_id": { - "placementId": "placement-id-1" - } - }], - "site": { - "domain": "https://test.com", - "referrer": "https://test.com/2016/06/12" - } - }, - "impIDs": [ - "001" - ] - }, - "mockResponse": { - "status": 200, - "body": "malformed body!" - } - }], - - "expectedMakeBidsErrors": [ - { - "value": "json: cannot unmarshal string into Go value of type resetdigital.resetDigitalBidResponse", - "comparison": "literal" - } - ] - } - \ No newline at end of file diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/missing-currency.json b/adapters/resetdigital/resetdigitaltest/supplemental/missing-currency.json deleted file mode 100644 index bd438f7857..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/missing-currency.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "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": { - "sizes": [ - [ - 250, - 300 - ] - ] - }, - "video": {}, - "audio": {} - }, - "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": "test markup" - }] - } - } - }], - - "expectedBidResponses": [{ - "currency": "USD", - "bids": [{ - "bid": { - "adm": "test markup", - "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/mtype-audio.json b/adapters/resetdigital/resetdigitaltest/supplemental/mtype-audio.json new file mode 100644 index 0000000000..2b790feee4 --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/mtype-audio.json @@ -0,0 +1,95 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": ["audio/mp4"], + "protocols": [2, 3, 5, 6] + }, + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-placement", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": ["audio/mp4"], + "protocols": [2, 3, 5, 6] + }, + "tagid": "test-placement", + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + }, + "cur": [ + "USD" + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.8, + "adm": "", + "crid": "test-creative-id", + "mtype": 3 + } + ], + "seat": "resetdigital" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.8, + "adm": "", + "crid": "test-creative-id", + "mtype": 3 + }, + "type": "audio", + "seat": "resetdigital" + } + ] + } + ] +} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/mtype-banner.json b/adapters/resetdigital/resetdigitaltest/supplemental/mtype-banner.json new file mode 100644 index 0000000000..25f1ad849b --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/mtype-banner.json @@ -0,0 +1,107 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-placement", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "test-placement", + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + }, + "cur": [ + "USD" + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
test ad
", + "crid": "test-creative-id", + "w": 300, + "h": 250, + "mtype": 1 + } + ], + "seat": "resetdigital" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
test ad
", + "crid": "test-creative-id", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner", + "seat": "resetdigital" + } + ] + } + ] +} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/mtype-native.json b/adapters/resetdigital/resetdigitaltest/supplemental/mtype-native.json new file mode 100644 index 0000000000..3e6347322d --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/mtype-native.json @@ -0,0 +1,93 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":80}}]}" + }, + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-placement", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":80}}]}" + }, + "tagid": "test-placement", + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + }, + "cur": [ + "USD" + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.0, + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Title\"}}]}}", + "crid": "test-creative-id", + "mtype": 4 + } + ], + "seat": "resetdigital" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.0, + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Title\"}}]}}", + "crid": "test-creative-id", + "mtype": 4 + }, + "type": "native", + "seat": "resetdigital" + } + ] + } + ] +} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/mtype-video.json b/adapters/resetdigital/resetdigitaltest/supplemental/mtype-video.json new file mode 100644 index 0000000000..0589a8da5b --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/mtype-video.json @@ -0,0 +1,103 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 3, 5, 6], + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-placement", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 3, 5, 6], + "w": 640, + "h": 480 + }, + "tagid": "test-placement", + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + }, + "cur": [ + "USD" + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.5, + "adm": "", + "crid": "test-creative-id", + "w": 640, + "h": 480, + "mtype": 2 + } + ], + "seat": "resetdigital" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.5, + "adm": "", + "crid": "test-creative-id", + "w": 640, + "h": 480, + "mtype": 2 + }, + "type": "video", + "seat": "resetdigital" + } + ] + } + ] +} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/multi-format.json b/adapters/resetdigital/resetdigitaltest/supplemental/multi-format.json deleted file mode 100644 index 4de554752f..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/multi-format.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "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": { - "sizes": [ - [ - 300, - 600 - ] - ] - }, - "video": {}, - "audio": {} - }, - "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": "video", - "seat": "resetdigital" - }] - }] - } - \ No newline at end of file diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/multiple-bids.json b/adapters/resetdigital/resetdigitaltest/supplemental/multiple-bids.json deleted file mode 100644 index 8892994d73..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/multiple-bids.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "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": { - "sizes": [ - [ - 250, - 300 - ] - ] - }, - "video": {}, - "audio": {} - }, - "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": "test markup" - }, - { - "bid_id": "02", - "imp_id": "001", - "cpm": 1.10, - "cid": "1002089", - "crid": "1000763-1002089", - "adid": "1002089", - "w": "300", - "h": "250", - "seat": "resetdigital", - "html": "test markup" - }] - } - } - }], - - "expectedMakeBidsErrors": [ - { - "value": "expected exactly one bid in the response, but got 2", - "comparison": "literal" - } - ] - } - \ No newline at end of file diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/multiple-imp-error.json b/adapters/resetdigital/resetdigitaltest/supplemental/multiple-imp-error.json new file mode 100644 index 0000000000..81ee3ec8df --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/multiple-imp-error.json @@ -0,0 +1,49 @@ +{ + "mockBidRequest": { + "id": "test-multi-request-id", + "imp": [ + { + "id": "test-imp-banner-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placement_id": "test-banner-placement" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 3, 5, 6], + "w": 640, + "h": 480, + "linearity": 1, + "maxduration": 30 + }, + "ext": { + "bidder": { + "placement_id": "test-video-placement" + } + } + } + ], + "site": { + "page": "https://example.com/multi", + "domain": "example.com" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "ResetDigital adapter supports only one impression per request", + "comparison": "literal" + } + ] +} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/native-mediatype.json b/adapters/resetdigital/resetdigitaltest/supplemental/native-mediatype.json new file mode 100644 index 0000000000..13a660cf6b --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/native-mediatype.json @@ -0,0 +1,91 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":80}}]}" + }, + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-placement", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":80}}]}" + }, + "tagid": "test-placement", + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + }, + "cur": [ + "USD" + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.0, + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Title\"}}]}}", + "crid": "test-creative-id" + } + ], + "seat": "resetdigital" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.0, + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Title\"}}]}}", + "crid": "test-creative-id" + }, + "type": "native", + "seat": "resetdigital" + } + ] + } + ] +} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/no-matching-impression.json b/adapters/resetdigital/resetdigitaltest/supplemental/no-matching-impression.json new file mode 100644 index 0000000000..64656b0b4f --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/no-matching-impression.json @@ -0,0 +1,97 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-placement", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "test-placement", + "ext": { + "bidder": { + "placement_id": "test-placement" + } + } + } + ], + "site": { + "page": "https://example.com" + }, + "cur": [ + "USD" + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "wrong-imp-id", + "price": 1.5, + "adm": "
test ad
", + "crid": "test-creative-id", + "w": 300, + "h": 250 + } + ], + "seat": "resetdigital" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "no matching impression found for ImpID: wrong-imp-id", + "comparison": "literal" + } + ] +} diff --git a/adapters/adsinteractive/adsinteractivetest/supplemental/bad-request-400.json b/adapters/resetdigital/resetdigitaltest/supplemental/status-400.json similarity index 65% rename from adapters/adsinteractive/adsinteractivetest/supplemental/bad-request-400.json rename to adapters/resetdigital/resetdigitaltest/supplemental/status-400.json index d584c81144..435182924d 100644 --- a/adapters/adsinteractive/adsinteractivetest/supplemental/bad-request-400.json +++ b/adapters/resetdigital/resetdigitaltest/supplemental/status-400.json @@ -14,18 +14,19 @@ }, "ext": { "bidder": { - "adUnit": "fake-adunit-name" + "placement_id": "test-placement" } } } - ] + ], + "site": { + "page": "https://example.com" + } }, - "httpCalls": [ { - "expectedRequest": { - "uri": "http://bid.adsinteractive.com/prebid", + "uri": "https://example.com?pid=test-placement", "body": { "id": "test-request-id", "imp": [ @@ -39,15 +40,22 @@ } ] }, + "tagid": "test-placement", "ext": { "bidder": { - "adUnit": "fake-adunit-name" + "placement_id": "test-placement" } } } + ], + "site": { + "page": "https://example.com" + }, + "cur": [ + "USD" ] }, - "impIDs":["test-imp-id"] + "impIDs": ["test-imp-id"] }, "mockResponse": { "status": 400, @@ -55,10 +63,9 @@ } } ], - "expectedMakeBidsErrors": [ { - "value": "Unexpected status code: 400. Bad request from publisher. Run with request.debug = 1 for more info.", + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", "comparison": "literal" } ] diff --git a/adapters/adsinteractive/adsinteractivetest/supplemental/service-unavailable-503.json b/adapters/resetdigital/resetdigitaltest/supplemental/status-500.json similarity index 64% rename from adapters/adsinteractive/adsinteractivetest/supplemental/service-unavailable-503.json rename to adapters/resetdigital/resetdigitaltest/supplemental/status-500.json index 2800076417..e151f38500 100644 --- a/adapters/adsinteractive/adsinteractivetest/supplemental/service-unavailable-503.json +++ b/adapters/resetdigital/resetdigitaltest/supplemental/status-500.json @@ -14,17 +14,19 @@ }, "ext": { "bidder": { - "adUnit": "fake-adunit-name" + "placement_id": "test-placement" } } } - ] + ], + "site": { + "page": "https://example.com" + } }, - "httpCalls": [ { "expectedRequest": { - "uri": "http://bid.adsinteractive.com/prebid", + "uri": "https://example.com?pid=test-placement", "body": { "id": "test-request-id", "imp": [ @@ -38,26 +40,32 @@ } ] }, + "tagid": "test-placement", "ext": { "bidder": { - "adUnit": "fake-adunit-name" + "placement_id": "test-placement" } } } + ], + "site": { + "page": "https://example.com" + }, + "cur": [ + "USD" ] }, - "impIDs":["test-imp-id"] + "impIDs": ["test-imp-id"] }, "mockResponse": { - "status": 503, + "status": 500, "body": {} } } ], - "expectedMakeBidsErrors": [ { - "value": "Unexpected status code: 503. Run with request.debug = 1 for more info.", + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", "comparison": "literal" } ] diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/unknown-media.json b/adapters/resetdigital/resetdigitaltest/supplemental/unknown-media.json deleted file mode 100644 index 5d9fb57363..0000000000 --- a/adapters/resetdigital/resetdigitaltest/supplemental/unknown-media.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "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": {}, - "video": {}, - "audio": { - "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/resetdigital/resetdigitaltest/supplemental/zero-price-bid.json b/adapters/resetdigital/resetdigitaltest/supplemental/zero-price-bid.json new file mode 100644 index 0000000000..eab76ee66a --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/zero-price-bid.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "test-zero-price-request-id", + "imp": [ + { + "id": "test-zero-price-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placement_id": "test-zero-price-placement" + } + } + } + ], + "site": { + "page": "https://example.com/zero-price", + "domain": "example.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-zero-price-placement", + "body": { + "id": "test-zero-price-request-id", + "imp": [ + { + "id": "test-zero-price-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "test-zero-price-placement", + "ext": { + "bidder": { + "placement_id": "test-zero-price-placement" + } + } + } + ], + "site": { + "page": "https://example.com/zero-price", + "domain": "example.com" + }, + "cur": [ + "USD" + ] + }, + "headers": { + "Content-Type": [ + "application/json" + ], + "Accept": [ + "application/json" + ], + "X-OpenRTB-Version": [ + "2.6" + ] + }, + "impIDs": ["test-zero-price-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-zero-price-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-zero-price-bid-id", + "impid": "test-zero-price-imp-id", + "price": 0.0, + "adm": "
test zero price ad
", + "crid": "test-zero-price-creative-id", + "w": 300, + "h": 250, + "adomain": ["example.com"] + } + ], + "seat": "resetdigital" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "price 0.000000 <= 0 filtered out", + "comparison": "literal" + } + ] +} diff --git a/adapters/resetdigital/resetdigitaltest/video/simple-video.json b/adapters/resetdigital/resetdigitaltest/video/simple-video.json new file mode 100644 index 0000000000..fc62f5d85d --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/video/simple-video.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-video-request-id", + "imp": [ + { + "id": "test-video-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 3, 5, 6], + "w": 640, + "h": 480, + "linearity": 1, + "maxduration": 30 + }, + "ext": { + "bidder": { + "placement_id": "test-video-placement" + } + } + } + ], + "site": { + "page": "https://example.com/video", + "domain": "example.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com?pid=test-video-placement", + "body": { + "id": "test-video-request-id", + "imp": [ + { + "id": "test-video-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 3, 5, 6], + "w": 640, + "h": 480, + "linearity": 1, + "maxduration": 30 + }, + "tagid": "test-video-placement", + "ext": { + "bidder": { + "placement_id": "test-video-placement" + } + } + } + ], + "site": { + "page": "https://example.com/video", + "domain": "example.com" + }, + "cur": [ + "USD" + ] + }, + "headers": { + "Content-Type": [ + "application/json" + ], + "Accept": [ + "application/json" + ], + "X-OpenRTB-Version": [ + "2.6" + ] + }, + "impIDs": ["test-video-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-video-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-video-bid-id", + "impid": "test-video-imp-id", + "price": 5.01, + "adm": "", + "crid": "test-video-creative-id", + "w": 640, + "h": 480, + "adomain": ["example.com"], + "mtype": 2 + } + ], + "seat": "resetdigital" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-video-bid-id", + "impid": "test-video-imp-id", + "price": 5.01, + "adm": "", + "crid": "test-video-creative-id", + "w": 640, + "h": 480, + "adomain": ["example.com"], + "mtype": 2 + }, + "type": "video", + "seat": "resetdigital" + } + ] + } + ] +} diff --git a/adapters/response.go b/adapters/response.go index ec02513ca6..6c3c6a8237 100644 --- a/adapters/response.go +++ b/adapters/response.go @@ -4,7 +4,7 @@ import ( "fmt" "net/http" - "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v4/errortypes" ) func CheckResponseStatusCodeForErrors(response *ResponseData) error { diff --git a/adapters/response_test.go b/adapters/response_test.go index 28fbefdf52..70106756b4 100644 --- a/adapters/response_test.go +++ b/adapters/response_test.go @@ -3,7 +3,7 @@ package adapters import ( "testing" - "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v4/errortypes" "github.com/stretchr/testify/assert" ) diff --git a/adapters/revcontent/revcontent.go b/adapters/revcontent/revcontent.go index 881b1d4916..7793e6fdd1 100644 --- a/adapters/revcontent/revcontent.go +++ b/adapters/revcontent/revcontent.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/revcontent/revcontent_test.go b/adapters/revcontent/revcontent_test.go index 35e6970c7f..5b266e2fcd 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/richaudience/params_test.go b/adapters/richaudience/params_test.go index 8f5b2e244b..f0bf685372 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/richaudience/richaudience.go b/adapters/richaudience/richaudience.go index 969fd312c9..0d8b5d2e29 100644 --- a/adapters/richaudience/richaudience.go +++ b/adapters/richaudience/richaudience.go @@ -7,11 +7,11 @@ import ( "net/url" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/richaudience/richaudience_test.go b/adapters/richaudience/richaudience_test.go index 342301f808..a55e5225d1 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/rise/rise.go b/adapters/rise/rise.go index 9a438f6dac..d9d9c2a4bc 100644 --- a/adapters/rise/rise.go +++ b/adapters/rise/rise.go @@ -9,10 +9,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // adapter is a Rise implementation of the adapters.Bidder interface. diff --git a/adapters/rise/rise_test.go b/adapters/rise/rise_test.go index d7235a7f3f..8d10cedb95 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testsDir = "risetest" diff --git a/adapters/roulax/roulax.go b/adapters/roulax/roulax.go index 9923836908..c5af6833fc 100644 --- a/adapters/roulax/roulax.go +++ b/adapters/roulax/roulax.go @@ -7,11 +7,11 @@ import ( "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/macros" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/roulax/roulax_test.go b/adapters/roulax/roulax_test.go index 3bd03bbbf3..67744873da 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testsDir = "roulaxtest" diff --git a/adapters/rtbhouse/rtbhouse.go b/adapters/rtbhouse/rtbhouse.go index c6445f1f15..03432e55c1 100644 --- a/adapters/rtbhouse/rtbhouse.go +++ b/adapters/rtbhouse/rtbhouse.go @@ -10,11 +10,11 @@ import ( "github.com/buger/jsonparser" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( @@ -59,7 +59,15 @@ func (adapter *RTBHouseAdapter) MakeRequests( var publisherId string for _, imp := range openRTBRequest.Imp { - rtbhouseExt, err := getImpressionExt(imp) + var impExtMap map[string]interface{} + err := jsonutil.Unmarshal(imp.Ext, &impExtMap) + if err != nil { + return nil, []error{&errortypes.BadInput{ + Message: "Bidder extension not provided or can't be unmarshalled", + }} + } + + rtbhouseExt, err := getImpressionExt(imp.Ext) if err != nil { return nil, []error{err} } @@ -100,9 +108,13 @@ func (adapter *RTBHouseAdapter) MakeRequests( imp.BidFloor = bidFloor } - // remove PAAPI signals from imp.Ext. RTB House pauses PAAPI support, - // the bidder should not get any PAAPI signals - newImpExt, err := clearAuctionEnvironment(&imp) + if imp.TagID == "" { + imp.TagID = getTagIDFromImpExt(impExtMap, imp.ID) + } + + // remove PAAPI signals + clearAuctionEnvironment(impExtMap) + newImpExt, err := jsonutil.Marshal(impExtMap) if err != nil { errs = append(errs, err) return nil, errs @@ -199,32 +211,39 @@ func setPublisherID(request *openrtb2.BidRequest, publisherId string) error { return nil } -func clearAuctionEnvironment(imp *openrtb2.Imp) (json.RawMessage, error) { - var objmap map[string]interface{} - err := json.Unmarshal(imp.Ext, &objmap) - if err != nil { - return nil, err - } - +func clearAuctionEnvironment(impExtMap map[string]interface{}) { keysToDelete := []string{"ae", "igs", "paapi"} for _, key := range keysToDelete { - _, exists := objmap[key] - if exists { - delete(objmap, key) - } + delete(impExtMap, key) } +} - newImpExt, err := json.Marshal(objmap) - if err != nil { - return nil, err +func getTagIDFromImpExt(impExtMap map[string]interface{}, impID string) string { + if gpid, ok := impExtMap["gpid"].(string); ok && gpid != "" { + return gpid } - return newImpExt, nil + dataMap, hasData := impExtMap["data"].(map[string]interface{}) + if hasData { + // imp.ext.data.adserver.adslot + if adserver, ok := dataMap["adserver"].(map[string]interface{}); ok { + if adslot, ok := adserver["adslot"].(string); ok && adslot != "" { + return adslot + } + } + + if pbAdSlot, ok := dataMap["pbadslot"].(string); ok && pbAdSlot != "" { + return pbAdSlot + } + } + + // imp.ID as fallback + return impID } -func getImpressionExt(imp openrtb2.Imp) (*openrtb_ext.ExtImpRTBHouse, error) { +func getImpressionExt(impExt json.RawMessage) (*openrtb_ext.ExtImpRTBHouse, error) { var bidderExt adapters.ExtImpBidder - if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(impExt, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "Bidder extension not provided or can't be unmarshalled", } @@ -236,7 +255,6 @@ func getImpressionExt(imp openrtb2.Imp) (*openrtb_ext.ExtImpRTBHouse, error) { Message: "Error while unmarshaling bidder extension", } } - return &rtbhouseExt, nil } diff --git a/adapters/rtbhouse/rtbhouse_test.go b/adapters/rtbhouse/rtbhouse_test.go index c7189cffc9..8dde82f949 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testsDir = "rtbhousetest" diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/ae-igs-removal.json b/adapters/rtbhouse/rtbhousetest/exemplary/ae-igs-removal.json index 7cf35414aa..bfb2c55af5 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/ae-igs-removal.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/ae-igs-removal.json @@ -36,6 +36,7 @@ ], "imp": [ { + "id": "test-imp-id", "banner": { "format": [ { @@ -50,7 +51,7 @@ }, "someOtherField": "should-remain" }, - "id": "test-imp-id" + "tagid": "test-imp-id" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/app-with-publisher.json b/adapters/rtbhouse/rtbhousetest/exemplary/app-with-publisher.json index d53ab37f2d..6ccac25098 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/app-with-publisher.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/app-with-publisher.json @@ -59,7 +59,8 @@ "publisherId": "app-publisher-123" } }, - "id": "test-imp-id" + "id": "test-imp-id", + "tagid": "test-imp-id" } ] }, diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/app_banner.json b/adapters/rtbhouse/rtbhousetest/exemplary/app_banner.json index ba14e50d88..8a39951ee9 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/app_banner.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/app_banner.json @@ -49,7 +49,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-imp-id" }] }, "impIDs":["test-imp-id"] diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/app_native.json b/adapters/rtbhouse/rtbhousetest/exemplary/app_native.json index bdd5e57350..272a10f5a1 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/app_native.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/app_native.json @@ -43,7 +43,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-native-imp" } ], "app": { diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/banner-resolve-macros.json b/adapters/rtbhouse/rtbhousetest/exemplary/banner-resolve-macros.json index eaa3965040..55c054d545 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/banner-resolve-macros.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/banner-resolve-macros.json @@ -37,7 +37,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-imp-id" }] }, "impIDs":["test-imp-id"] diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json index d31110cb3e..a9ede9271e 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json @@ -60,7 +60,8 @@ "bidfloor": 3.00 } }, - "id": "test-imp-id" + "id": "test-imp-id", + "tagid": "test-imp-id" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json index fd324fb034..bdc7eed6be 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json @@ -63,7 +63,8 @@ "bidfloor": 2 } }, - "id": "test-imp-id" + "id": "test-imp-id", + "tagid": "test-imp-id" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json index 24cc0822dd..97c9f2e59c 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json @@ -60,7 +60,8 @@ "publisherId": "12345" } }, - "id": "test-imp-id" + "id": "test-imp-id", + "tagid": "test-imp-id" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json index e579017c07..139a492ce5 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json @@ -58,7 +58,8 @@ "publisherId": "12345" } }, - "id": "test-imp-id" + "id": "test-imp-id", + "tagid": "test-imp-id" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/existing-site-publisher-override.json b/adapters/rtbhouse/rtbhousetest/exemplary/existing-site-publisher-override.json index 235e2c4a8b..a45e84bb7b 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/existing-site-publisher-override.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/existing-site-publisher-override.json @@ -63,7 +63,8 @@ "publisherId": "new-publisher-123" } }, - "id": "test-imp-id" + "id": "test-imp-id", + "tagid": "test-imp-id" } ] }, diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/multiple-imps-different-publishers.json b/adapters/rtbhouse/rtbhousetest/exemplary/multiple-imps-different-publishers.json index 3cb44d5422..70cfc797b3 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/multiple-imps-different-publishers.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/multiple-imps-different-publishers.json @@ -60,7 +60,8 @@ "publisherId": "first-publisher" } }, - "id": "test-imp-id-1" + "id": "test-imp-id-1", + "tagid": "test-imp-id-1" }, { "banner": { @@ -76,7 +77,8 @@ "publisherId": "second-publisher" } }, - "id": "test-imp-id-2" + "id": "test-imp-id-2", + "tagid": "test-imp-id-2" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json index a4aa158053..ca898872a6 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json @@ -37,7 +37,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-native-imp" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json index 232a102ce7..5f5f6f1a2c 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json @@ -37,7 +37,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-native-imp" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/pmp-removal-test.json b/adapters/rtbhouse/rtbhousetest/exemplary/pmp-removal-test.json index 0d31ef3d5b..3b05d5c587 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/pmp-removal-test.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/pmp-removal-test.json @@ -53,7 +53,8 @@ "publisherId": "12345" } }, - "id": "test-imp-id" + "id": "test-imp-id", + "tagid": "test-imp-id" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner-paapi.json b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner-paapi.json index fb96bdff14..1a561ab573 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner-paapi.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner-paapi.json @@ -45,7 +45,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-imp-id" }] }, "impIDs":["test-imp-id"] diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json index 0cad5a6b96..61923eb38e 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json @@ -37,7 +37,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-imp-id" }] }, "impIDs":["test-imp-id"] diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/tagid-from-adserver-adslot.json b/adapters/rtbhouse/rtbhousetest/exemplary/tagid-from-adserver-adslot.json new file mode 100644 index 0000000000..e069a1fd84 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/tagid-from-adserver-adslot.json @@ -0,0 +1,123 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "data": { + "adserver": { + "adslot": "adserver_slot_value" + } + }, + "bidder": { + "publisherId": "12345" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "ext": { + "bidder": { + "publisherId": "12345" + }, + "data": { + "adserver": { + "adslot": "adserver_slot_value" + } + } + }, + "id": "test-imp-id", + "tagid": "adserver_slot_value" + } + ], + "site": { + "publisher": { + "ext": { + "prebid": { + "publisherId": "12345" + } + } + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/tagid-from-pbadslot.json b/adapters/rtbhouse/rtbhousetest/exemplary/tagid-from-pbadslot.json new file mode 100644 index 0000000000..2fa2988764 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/tagid-from-pbadslot.json @@ -0,0 +1,119 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "data": { + "pbadslot": "pbslot_value" + }, + "bidder": { + "publisherId": "12345" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "ext": { + "bidder": { + "publisherId": "12345" + }, + "data": { + "pbadslot": "pbslot_value" + } + }, + "id": "test-imp-id", + "tagid": "pbslot_value" + } + ], + "site": { + "publisher": { + "ext": { + "prebid": { + "publisherId": "12345" + } + } + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/tagid-precedence-gpid-over-pbadslot.json b/adapters/rtbhouse/rtbhousetest/exemplary/tagid-precedence-gpid-over-pbadslot.json new file mode 100644 index 0000000000..df1b7c3faf --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/tagid-precedence-gpid-over-pbadslot.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "gpid": "gpid_value", + "data": { + "pbadslot": "pbslot_value" + }, + "bidder": { + "publisherId": "12345" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "ext": { + "bidder": { + "publisherId": "12345" + }, + "gpid": "gpid_value", + "data": { + "pbadslot": "pbslot_value" + } + }, + "id": "test-imp-id", + "tagid": "gpid_value" + } + ], + "site": { + "publisher": { + "ext": { + "prebid": { + "publisherId": "12345" + } + } + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/adsinteractive/adsinteractivetest/exemplary/banner.json b/adapters/rtbhouse/rtbhousetest/exemplary/tagid-preservation-existing.json similarity index 54% rename from adapters/adsinteractive/adsinteractivetest/exemplary/banner.json rename to adapters/rtbhouse/rtbhousetest/exemplary/tagid-preservation-existing.json index bc4d4c7091..785991f05b 100644 --- a/adapters/adsinteractive/adsinteractivetest/exemplary/banner.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/tagid-preservation-existing.json @@ -1,90 +1,116 @@ { "mockBidRequest": { "id": "test-request-id", - "site": { - "page": "https://good.site/url" - }, "imp": [ { "id": "test-imp-id", + "tagid": "existing_tag", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, "ext": { + "gpid": "gpid_value", "bidder": { - "adUnit": "fake-adunit-name" + "publisherId": "12345" } } } ] }, - "httpCalls": [ { "expectedRequest": { - "uri": "http://bid.adsinteractive.com/prebid", + "uri": "http://localhost/prebid_server", "body": { "id": "test-request-id", - "site": { - "page": "https://good.site/url" - }, + "cur": [ + "USD" + ], "imp": [ { - "id": "test-imp-id", + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, "ext": { "bidder": { - "adUnit": "fake-adunit-name" + "publisherId": "12345" + }, + "gpid": "gpid_value" + }, + "id": "test-imp-id", + "tagid": "existing_tag" + } + ], + "site": { + "publisher": { + "ext": { + "prebid": { + "publisherId": "12345" } } } - ] + } }, - "impIDs":["test-imp-id"] + "impIDs": ["test-imp-id"] }, "mockResponse": { "status": 200, "body": { - "id": "test-request-id", + "id": "test-response-id", + "cur": "USD", "seatbid": [ { - "seat": "adsinteractive", + "seat": "rtbhouse", "bid": [ { "id": "randomid", "impid": "test-imp-id", - "price": 0.72, + "price": 300, "adid": "12345678", "adm": "some-test-ad", "cid": "987", "crid": "12345678", "h": 250, - "w": 300 + "w": 300, + "mtype": 1 } ] } - ], - "cur": "EUR" + ] } } } ], - "expectedBidResponses": [ { - "currency": "EUR", + "currency": "USD", "bids": [ { "bid": { "id": "randomid", "impid": "test-imp-id", - "price": 0.72, - "adm": "some-test-ad", + "price": 300, "adid": "12345678", + "adm": "some-test-ad", "cid": "987", "crid": "12345678", + "h": 250, "w": 300, - "h": 250 + "mtype": 1 }, "type": "banner" } ] } ] -} +} \ No newline at end of file diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json b/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json index 71b95d18db..e1389acece 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json @@ -62,7 +62,8 @@ "bidfloor": 2 } }, - "id": "test-imp-id" + "id": "test-imp-id", + "tagid": "test-imp-id" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json b/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json index a2d0c8da3d..dc61c6d061 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json @@ -41,7 +41,8 @@ "ext": { "bidder": { } - } + }, + "tagid": "test-imp-id" } ] }, diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json b/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json index 4f643d1842..9229cd58ec 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json @@ -49,7 +49,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-native-imp" }, { "id": "test-banner-imp", @@ -61,7 +62,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-banner-imp" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json index bfdf568d3c..99dc0bcbb9 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json @@ -37,7 +37,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-native-imp" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json index 4e95d2e23c..6a1c564e46 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json @@ -37,7 +37,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-native-imp" } ], "site": { diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json index 3b92e5d8fd..385f807a49 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json @@ -46,7 +46,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-imp-id" } ] }, diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json index 58bdab87eb..d73090b0b1 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json @@ -46,7 +46,8 @@ }, "ext": { "bidder": {} - } + }, + "tagid": "test-imp-id" } ] }, diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json b/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json index 03a69c2617..8258d37698 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json @@ -41,7 +41,8 @@ "ext": { "bidder": { } - } + }, + "tagid": "test-imp-id" } ] }, diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json b/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json index 25f8778636..06fcf177af 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json @@ -41,7 +41,8 @@ "ext": { "bidder": { } - } + }, + "tagid": "test-imp-id" } ] }, diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json b/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json index 27073b0e0c..f27138969d 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json @@ -41,7 +41,8 @@ "ext": { "bidder": { } - } + }, + "tagid": "test-imp-id" } ] }, diff --git a/adapters/rtbstack/params_test.go b/adapters/rtbstack/params_test.go new file mode 100644 index 0000000000..087302decb --- /dev/null +++ b/adapters/rtbstack/params_test.go @@ -0,0 +1,57 @@ +package rtbstack + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/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.BidderRTBStack, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected rtbstack 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.BidderRTBStack, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"route":"https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145","tagId":"12345"}`, + `{"route":"https://site.eu-adx-admixer.rtb-stack.com/prebid?client=abc&endpoint=1&ssp=2","tagId":"tag1"}`, + `{"route":"https://site.asia-adx-admixer.rtb-stack.com/prebid?client=abc&endpoint=1&ssp=2","tagId":"tag1","customParams":{"foo":"bar"}}`, + `{"route":"https://example.us-adx-admixer.rtb-stack.com/prebid?client=abc&endpoint=1&ssp=2","tagId":"tag1","customParams":{}}`, + `{"route":"https://example.us-adx-admixer.rtb-stack.com/prebid?client=abc&endpoint=1&ssp=2","tagId":"tag1","customParams":{"nested":{"key":"value"}}}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"route":"https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=abc&endpoint=1&ssp=2"}`, + `{"tagId":"12345"}`, + `{"route":"","tagId":"12345"}`, + `{"route":123,"tagId":"12345"}`, + `{"route":"https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=abc&endpoint=1&ssp=2","tagId":123}`, +} diff --git a/adapters/rtbstack/rtbstack.go b/adapters/rtbstack/rtbstack.go new file mode 100644 index 0000000000..5b5b73f0a3 --- /dev/null +++ b/adapters/rtbstack/rtbstack.go @@ -0,0 +1,269 @@ +package rtbstack + +import ( + "fmt" + "net/http" + "net/url" + "strings" + "text/template" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint *template.Template +} + +// impCtx represents the context containing an OpenRTB impression and its corresponding RTBStack extension configuration. +type impCtx struct { + imp openrtb2.Imp + rtbStackExt *openrtb_ext.ExtImpRTBStack +} + +// extImpRTBStack is used for imp->ext when sending to rtb-stack backend. +type extImpRTBStack struct { + CustomParams map[string]interface{} `json:"customParams,omitempty"` +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + tpl, 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: tpl, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + if len(request.Imp) == 0 { + return nil, []error{&errortypes.BadInput{ + Message: "No impressions in request", + }} + } + + var errs []error + impsByRoute := make(map[string][]*impCtx) + var routeOrder []string + + for i := range request.Imp { + imp, ext, err := preprocessImp(request.Imp[i]) + if err != nil { + errs = append(errs, err) + continue + } + + ctx := &impCtx{ + imp: imp, + rtbStackExt: ext, + } + if _, ok := impsByRoute[ext.Route]; !ok { + routeOrder = append(routeOrder, ext.Route) + } + impsByRoute[ext.Route] = append(impsByRoute[ext.Route], ctx) + } + + if len(routeOrder) == 0 { + return nil, errs + } + + var newSite *openrtb2.Site + if request.Site != nil && request.Site.Domain == "" { + siteCopy := *request.Site + pageURL, parseErr := url.Parse(request.Site.Page) + if parseErr == nil && pageURL.Hostname() != "" { + siteCopy.Domain = pageURL.Hostname() + } else { + siteCopy.Domain = request.Site.Page + } + newSite = &siteCopy + } + + requests := make([]*adapters.RequestData, 0, len(routeOrder)) + for _, route := range routeOrder { + group := impsByRoute[route] + + endpoint, err := a.buildEndpointURL(group[0].rtbStackExt) + if err != nil { + errs = append(errs, err) + continue + } + + processedImps := make([]openrtb2.Imp, 0, len(group)) + for _, v := range group { + processedImps = append(processedImps, v.imp) + } + + newRequest := *request + newRequest.Imp = processedImps + if newSite != nil { + newRequest.Site = newSite + } + + reqJSON, err := jsonutil.Marshal(newRequest) + if err != nil { + errs = append(errs, &errortypes.FailedToRequestBids{ + Message: "Error parsing reqJSON object", + }) + continue + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + requests = append(requests, &adapters.RequestData{ + Method: http.MethodPost, + Uri: endpoint, + Body: reqJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(newRequest.Imp), + }) + } + + if len(requests) == 0 { + return nil, errs + } + + return requests, errs +} + +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} + } + + if len(bidResp.SeatBid) == 0 { + return nil, nil + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(internalRequest.Imp)) + + if bidResp.Cur != "" { + bidResponse.Currency = bidResp.Cur + } + + var bidErrs []error + for _, sb := range bidResp.SeatBid { + for i := range sb.Bid { + bidType, err := getMediaTypeForBid(sb.Bid[i]) + if err != nil { + bidErrs = append(bidErrs, err) + continue + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &sb.Bid[i], + BidType: bidType, + }) + } + } + return bidResponse, bidErrs +} + +var validRegions = map[string]bool{"us": true, "eu": true, "sg": true} + +func (a *adapter) buildEndpointURL(ext *openrtb_ext.ExtImpRTBStack) (string, error) { + routeURL, err := url.Parse(ext.Route) + if err != nil { + return "", &errortypes.BadInput{Message: fmt.Sprintf("invalid route URL: %v", err)} + } + + region, err := extractRegion(routeURL.Hostname()) + if err != nil { + return "", err + } + + queryParams := routeURL.Query() + client := queryParams.Get("client") + endpoint := queryParams.Get("endpoint") + ssp := queryParams.Get("ssp") + + if client == "" || endpoint == "" || ssp == "" { + return "", &errortypes.BadInput{Message: "route URL must contain client, endpoint, and ssp query parameters"} + } + + params := macros.EndpointTemplateParams{ + Region: region, + SspID: ssp, + ZoneID: endpoint, + PartnerId: client, + } + + return macros.ResolveMacros(a.endpoint, params) +} + +func extractRegion(hostname string) (string, error) { + parts := strings.Split(hostname, ".") + for _, part := range parts { + if strings.HasSuffix(part, "-adx-admixer") { + region := strings.ToLower(strings.TrimSuffix(part, "-adx-admixer")) + if validRegions[region] { + return region, nil + } + } + } + return "", &errortypes.BadInput{Message: "unable to extract valid region from route URL hostname"} +} + +func preprocessImp( + imp openrtb2.Imp, +) (openrtb2.Imp, *openrtb_ext.ExtImpRTBStack, error) { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return imp, nil, &errortypes.BadInput{Message: err.Error()} + } + + var impExt openrtb_ext.ExtImpRTBStack + if err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt); err != nil { + return imp, nil, &errortypes.BadInput{ + Message: "Wrong RTBStack bidder ext", + } + } + + imp.TagID = impExt.TagId + + newExt := extImpRTBStack{ + CustomParams: impExt.CustomParams, + } + + newImpExtForRTBStack, err := jsonutil.Marshal(newExt) + if err != nil { + return imp, nil, &errortypes.BadInput{Message: err.Error()} + } + imp.Ext = newImpExtForRTBStack + + return imp, &impExt, nil +} + +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 + 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 for bid %s", bid.MType, bid.ImpID), + } + } +} diff --git a/adapters/rtbstack/rtbstack_test.go b/adapters/rtbstack/rtbstack_test.go new file mode 100644 index 0000000000..a28237d4ca --- /dev/null +++ b/adapters/rtbstack/rtbstack_test.go @@ -0,0 +1,29 @@ +package rtbstack + +import ( + "testing" + + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderRTBStack, config.Adapter{ + Endpoint: "https://{{.Region}}-adx-admixer.rtb-stack.com/pbs?ssp={{.SspID}}&endpoint={{.ZoneID}}&client={{.PartnerId}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "rtbstacktest", bidder) +} + +func TestBuilderInvalidTemplate(t *testing.T) { + _, err := Builder(openrtb_ext.BidderRTBStack, config.Adapter{ + Endpoint: "https://{{.Region}-bad-template"}, config.Server{}) + + if err == nil { + t.Fatal("Builder should return an error for an invalid endpoint template") + } +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/app-audio.json b/adapters/rtbstack/rtbstacktest/exemplary/app-audio.json new file mode 100644 index 0000000000..437343b056 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/app-audio.json @@ -0,0 +1,162 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid.app" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-app-audio-short", + "audio": { + "mimes": [ + "audio/mpeg", + "audio/mp4" + ], + "minduration": 5, + "maxduration": 30 + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "app-audio-short", + "customParams": { + "foo": "bar" + } + } + } + }, + { + "id": "imp-app-audio-long", + "audio": { + "mimes": [ + "audio/mpeg", + "audio/mp4" + ], + "minduration": 15, + "maxduration": 60 + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "app-audio-long", + "customParams": {} + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid.app" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-app-audio-short", + "audio": { + "mimes": [ + "audio/mpeg", + "audio/mp4" + ], + "minduration": 5, + "maxduration": 30 + }, + "tagid": "app-audio-short", + "ext": { + "customParams": { + "foo": "bar" + } + } + }, + { + "id": "imp-app-audio-long", + "audio": { + "mimes": [ + "audio/mpeg", + "audio/mp4" + ], + "minduration": 15, + "maxduration": 60 + }, + "tagid": "app-audio-long", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-app-audio-short", + "imp-app-audio-long" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-app-audio-short-1", + "impid": "imp-app-audio-short", + "price": 0.75, + "adm": "", + "crid": "crid-app-audio-short-1", + "mtype": 3 + }, + { + "id": "bid-app-audio-long-1", + "impid": "imp-app-audio-long", + "price": 1.25, + "adm": "", + "crid": "crid-app-audio-long-1", + "mtype": 3 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-app-audio-short-1", + "impid": "imp-app-audio-short", + "price": 0.75, + "adm": "", + "crid": "crid-app-audio-short-1", + "mtype": 3 + }, + "type": "audio" + }, + { + "bid": { + "id": "bid-app-audio-long-1", + "impid": "imp-app-audio-long", + "price": 1.25, + "adm": "", + "crid": "crid-app-audio-long-1", + "mtype": 3 + }, + "type": "audio" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/app-banner.json b/adapters/rtbstack/rtbstacktest/exemplary/app-banner.json new file mode 100644 index 0000000000..1072a3946b --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/app-banner.json @@ -0,0 +1,162 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid.app" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-app-basic", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "app-basic", + "customParams": { + "foo": "bar" + } + } + } + }, + { + "id": "imp-app-large", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "app-large", + "customParams": {} + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid.app" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-app-basic", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "tagid": "app-basic", + "ext": { + "customParams": { + "foo": "bar" + } + } + }, + { + "id": "imp-app-large", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "app-large", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-app-basic", + "imp-app-large" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-app-basic-1", + "impid": "imp-app-basic", + "price": 0.95, + "adm": "
App Banner 320x50
", + "crid": "crid-app-basic-1", + "mtype": 1 + }, + { + "id": "bid-app-large-1", + "impid": "imp-app-large", + "price": 1.5, + "adm": "
App Banner 728x90
", + "crid": "crid-app-large-1", + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-app-basic-1", + "impid": "imp-app-basic", + "price": 0.95, + "adm": "
App Banner 320x50
", + "crid": "crid-app-basic-1", + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "bid-app-large-1", + "impid": "imp-app-large", + "price": 1.5, + "adm": "
App Banner 728x90
", + "crid": "crid-app-large-1", + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/app-native.json b/adapters/rtbstack/rtbstacktest/exemplary/app-native.json new file mode 100644 index 0000000000..af5549ff6c --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/app-native.json @@ -0,0 +1,146 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid.app" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-app-native-small", + "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\":50}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":120,\"hmin\":120,\"mimes\":[\"image/jpeg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":100}}]}" + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "app-native-small", + "customParams": { + "foo": "bar" + } + } + } + }, + { + "id": "imp-app-native-large", + "native": { + "ver": "1.1", + "request": "{\"ver\":\"1.0\",\"layout\":2,\"adunit\":2,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":300,\"hmin\":300,\"mimes\":[\"image/jpeg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":150}}]}" + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "app-native-large", + "customParams": {} + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid.app" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-app-native-small", + "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\":50}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":120,\"hmin\":120,\"mimes\":[\"image/jpeg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":100}}]}" + }, + "tagid": "app-native-small", + "ext": { + "customParams": { + "foo": "bar" + } + } + }, + { + "id": "imp-app-native-large", + "native": { + "ver": "1.1", + "request": "{\"ver\":\"1.0\",\"layout\":2,\"adunit\":2,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":300,\"hmin\":300,\"mimes\":[\"image/jpeg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":150}}]}" + }, + "tagid": "app-native-large", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-app-native-small", + "imp-app-native-large" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-app-native-small-1", + "impid": "imp-app-native-small", + "price": 1.5, + "adm": "{\"native\":{\"assets\":[{\"id\":1,\"title\":{\"text\":\"Small App Native Ad\"}}]}}", + "crid": "crid-app-native-small-1", + "mtype": 4 + }, + { + "id": "bid-app-native-large-1", + "impid": "imp-app-native-large", + "price": 2.75, + "adm": "{\"native\":{\"assets\":[{\"id\":1,\"title\":{\"text\":\"Large App Native Ad\"}}]}}", + "crid": "crid-app-native-large-1", + "mtype": 4 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-app-native-small-1", + "impid": "imp-app-native-small", + "price": 1.5, + "adm": "{\"native\":{\"assets\":[{\"id\":1,\"title\":{\"text\":\"Small App Native Ad\"}}]}}", + "crid": "crid-app-native-small-1", + "mtype": 4 + }, + "type": "native" + }, + { + "bid": { + "id": "bid-app-native-large-1", + "impid": "imp-app-native-large", + "price": 2.75, + "adm": "{\"native\":{\"assets\":[{\"id\":1,\"title\":{\"text\":\"Large App Native Ad\"}}]}}", + "crid": "crid-app-native-large-1", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/app-video.json b/adapters/rtbstack/rtbstacktest/exemplary/app-video.json new file mode 100644 index 0000000000..c2d5b4e6bc --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/app-video.json @@ -0,0 +1,188 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid.app" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-app-video-small", + "video": { + "w": 640, + "h": 360, + "mimes": [ + "video/mp4", + "video/webm" + ], + "minduration": 5, + "maxduration": 30, + "protocols": [ + 2, + 5 + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "app-video-small", + "customParams": { + "foo": "bar" + } + } + } + }, + { + "id": "imp-app-video-large", + "video": { + "w": 1280, + "h": 720, + "mimes": [ + "video/mp4", + "video/webm" + ], + "minduration": 10, + "maxduration": 60, + "protocols": [ + 2, + 5, + 6 + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "app-video-large", + "customParams": {} + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid.app" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-app-video-small", + "video": { + "w": 640, + "h": 360, + "mimes": [ + "video/mp4", + "video/webm" + ], + "minduration": 5, + "maxduration": 30, + "protocols": [ + 2, + 5 + ] + }, + "tagid": "app-video-small", + "ext": { + "customParams": { + "foo": "bar" + } + } + }, + { + "id": "imp-app-video-large", + "video": { + "w": 1280, + "h": 720, + "mimes": [ + "video/mp4", + "video/webm" + ], + "minduration": 10, + "maxduration": 60, + "protocols": [ + 2, + 5, + 6 + ] + }, + "tagid": "app-video-large", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-app-video-small", + "imp-app-video-large" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-app-video-small-1", + "impid": "imp-app-video-small", + "price": 3.0, + "adm": "App Small Video Ad", + "crid": "crid-app-video-small-1", + "mtype": 2 + }, + { + "id": "bid-app-video-large-1", + "impid": "imp-app-video-large", + "price": 5.5, + "adm": "App Large Video Ad", + "crid": "crid-app-video-large-1", + "mtype": 2 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-app-video-small-1", + "impid": "imp-app-video-small", + "price": 3.0, + "adm": "App Small Video Ad", + "crid": "crid-app-video-small-1", + "mtype": 2 + }, + "type": "video" + }, + { + "bid": { + "id": "bid-app-video-large-1", + "impid": "imp-app-video-large", + "price": 5.5, + "adm": "App Large Video Ad", + "crid": "crid-app-video-large-1", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/multi-route-grouping.json b/adapters/rtbstack/rtbstacktest/exemplary/multi-route-grouping.json new file mode 100644 index 0000000000..543b99815e --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/multi-route-grouping.json @@ -0,0 +1,235 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-route-a-1", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=client-a&endpoint=100&ssp=200", + "tagId": "tag-a-1" + } + } + }, + { + "id": "imp-route-b-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.eu-adx-admixer.rtb-stack.com/prebid?client=client-b&endpoint=300&ssp=400", + "tagId": "tag-b-1" + } + } + }, + { + "id": "imp-route-a-2", + "banner": { + "format": [ + { + "w": 970, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=client-a&endpoint=100&ssp=200", + "tagId": "tag-a-2" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=200&endpoint=100&client=client-a", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-route-a-1", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "tag-a-1", + "ext": {} + }, + { + "id": "imp-route-a-2", + "banner": { + "format": [ + { + "w": 970, + "h": 250 + } + ] + }, + "tagid": "tag-a-2", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-route-a-1", + "imp-route-a-2" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-a-1", + "impid": "imp-route-a-1", + "price": 1.25, + "adm": "
A1
", + "crid": "crid-a-1", + "mtype": 1 + }, + { + "id": "bid-a-2", + "impid": "imp-route-a-2", + "price": 2.5, + "adm": "
A2
", + "crid": "crid-a-2", + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "https://eu-adx-admixer.rtb-stack.com/pbs?ssp=400&endpoint=300&client=client-b", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-route-b-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "tag-b-1", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-route-b-1" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-b-1", + "impid": "imp-route-b-1", + "price": 0.75, + "adm": "
B1
", + "crid": "crid-b-1", + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-a-1", + "impid": "imp-route-a-1", + "price": 1.25, + "adm": "
A1
", + "crid": "crid-a-1", + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "bid-a-2", + "impid": "imp-route-a-2", + "price": 2.5, + "adm": "
A2
", + "crid": "crid-a-2", + "mtype": 1 + }, + "type": "banner" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-b-1", + "impid": "imp-route-b-1", + "price": 0.75, + "adm": "
B1
", + "crid": "crid-b-1", + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/multi-route-same.json b/adapters/rtbstack/rtbstacktest/exemplary/multi-route-same.json new file mode 100644 index 0000000000..a419ed2bcc --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/multi-route-same.json @@ -0,0 +1,162 @@ +{ + "mockBidRequest": { + "id": "test-request-same-route", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-same-1", + "banner": { + "format": [{ "w": 728, "h": 90 }] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=client-x&endpoint=500&ssp=600", + "tagId": "tag-1" + } + } + }, + { + "id": "imp-same-2", + "banner": { + "format": [{ "w": 300, "h": 250 }] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=client-x&endpoint=500&ssp=600", + "tagId": "tag-2" + } + } + }, + { + "id": "imp-same-3", + "banner": { + "format": [{ "w": 970, "h": 250 }] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=client-x&endpoint=500&ssp=600", + "tagId": "tag-3" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=600&endpoint=500&client=client-x", + "body": { + "id": "test-request-same-route", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-same-1", + "banner": { "format": [{ "w": 728, "h": 90 }] }, + "tagid": "tag-1", + "ext": {} + }, + { + "id": "imp-same-2", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "tagid": "tag-2", + "ext": {} + }, + { + "id": "imp-same-3", + "banner": { "format": [{ "w": 970, "h": 250 }] }, + "tagid": "tag-3", + "ext": {} + } + ] + }, + "impIDs": ["imp-same-1", "imp-same-2", "imp-same-3"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-same-route", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-same-1", + "impid": "imp-same-1", + "price": 1.10, + "adm": "
1
", + "crid": "crid-1", + "mtype": 1 + }, + { + "id": "bid-same-2", + "impid": "imp-same-2", + "price": 1.20, + "adm": "
2
", + "crid": "crid-2", + "mtype": 1 + }, + { + "id": "bid-same-3", + "impid": "imp-same-3", + "price": 1.30, + "adm": "
3
", + "crid": "crid-3", + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-same-1", + "impid": "imp-same-1", + "price": 1.10, + "adm": "
1
", + "crid": "crid-1", + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "bid-same-2", + "impid": "imp-same-2", + "price": 1.20, + "adm": "
2
", + "crid": "crid-2", + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "bid-same-3", + "impid": "imp-same-3", + "price": 1.30, + "adm": "
3
", + "crid": "crid-3", + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/no-currency-in-response.json b/adapters/rtbstack/rtbstacktest/exemplary/no-currency-in-response.json new file mode 100644 index 0000000000..8e3f949460 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/no-currency-in-response.json @@ -0,0 +1,99 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "test-tag" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "test-tag", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-banner" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-1", + "impid": "imp-banner", + "price": 1.0, + "adm": "
Banner
", + "crid": "crid-1", + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "imp-banner", + "price": 1.0, + "adm": "
Banner
", + "crid": "crid-1", + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/optional-params.json b/adapters/rtbstack/rtbstacktest/exemplary/optional-params.json new file mode 100644 index 0000000000..8e3f14abfd --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/optional-params.json @@ -0,0 +1,228 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "basic", + "customParams": { + "foo": "bar" + } + } + } + }, + { + "id": "imp-empty-custom", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "empty-custom", + "customParams": {} + } + } + }, + { + "id": "imp-numeric-bool", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "numeric-bool", + "customParams": { + "floor": 0.45, + "enabled": true, + "count": 3 + } + } + } + }, + { + "id": "imp-nested-custom", + "banner": { + "format": [ + { + "w": 970, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "nested", + "customParams": { + "placement": { + "position": "top", + "sticky": true + }, + "sizes": [ + "970x250", + "728x90" + ] + } + } + } + }, + { + "id": "imp-no-custom", + "banner": { + "format": [ + { + "w": 468, + "h": 60 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "no-custom" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "basic", + "ext": { + "customParams": { + "foo": "bar" + } + } + }, + { + "id": "imp-empty-custom", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "empty-custom", + "ext": {} + }, + { + "id": "imp-numeric-bool", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "tagid": "numeric-bool", + "ext": { + "customParams": { + "floor": 0.45, + "enabled": true, + "count": 3 + } + } + }, + { + "id": "imp-nested-custom", + "banner": { + "format": [ + { + "w": 970, + "h": 250 + } + ] + }, + "tagid": "nested", + "ext": { + "customParams": { + "placement": { + "position": "top", + "sticky": true + }, + "sizes": [ + "970x250", + "728x90" + ] + } + } + }, + { + "id": "imp-no-custom", + "banner": { + "format": [ + { + "w": 468, + "h": 60 + } + ] + }, + "tagid": "no-custom", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-basic", + "imp-empty-custom", + "imp-numeric-bool", + "imp-nested-custom", + "imp-no-custom" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/site-audio.json b/adapters/rtbstack/rtbstacktest/exemplary/site-audio.json new file mode 100644 index 0000000000..952d026e80 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/site-audio.json @@ -0,0 +1,158 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-audio-small", + "audio": { + "mimes": [ + "audio/mpeg", + "audio/mp4" + ], + "minduration": 5, + "maxduration": 30 + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "site-audio-small", + "customParams": { + "foo": "bar" + } + } + } + }, + { + "id": "imp-audio-large", + "audio": { + "mimes": [ + "audio/mpeg", + "audio/mp4" + ], + "minduration": 15, + "maxduration": 60 + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "site-audio-large", + "customParams": {} + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-audio-small", + "audio": { + "mimes": [ + "audio/mpeg", + "audio/mp4" + ], + "minduration": 5, + "maxduration": 30 + }, + "tagid": "site-audio-small", + "ext": { + "customParams": { + "foo": "bar" + } + } + }, + { + "id": "imp-audio-large", + "audio": { + "mimes": [ + "audio/mpeg", + "audio/mp4" + ], + "minduration": 15, + "maxduration": 60 + }, + "tagid": "site-audio-large", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-audio-small", + "imp-audio-large" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-site-audio-small-1", + "impid": "imp-audio-small", + "price": 0.75, + "adm": "", + "crid": "crid-site-audio-small-1", + "mtype": 3 + }, + { + "id": "bid-site-audio-large-1", + "impid": "imp-audio-large", + "price": 1.25, + "adm": "", + "crid": "crid-site-audio-large-1", + "mtype": 3 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-site-audio-small-1", + "impid": "imp-audio-small", + "price": 0.75, + "adm": "", + "crid": "crid-site-audio-small-1", + "mtype": 3 + }, + "type": "audio" + }, + { + "bid": { + "id": "bid-site-audio-large-1", + "impid": "imp-audio-large", + "price": 1.25, + "adm": "", + "crid": "crid-site-audio-large-1", + "mtype": 3 + }, + "type": "audio" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/site-banner.json b/adapters/rtbstack/rtbstacktest/exemplary/site-banner.json new file mode 100644 index 0000000000..2c0e908c6e --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/site-banner.json @@ -0,0 +1,229 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "basic", + "customParams": { + "foo": "bar" + } + } + } + }, + { + "id": "imp-empty-custom", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "empty-custom", + "customParams": {} + } + } + }, + { + "id": "imp-nested-custom", + "banner": { + "format": [ + { + "w": 970, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "nested", + "customParams": { + "placement": { + "position": "top", + "sticky": true + }, + "sizes": [ + "970x250", + "728x90" + ] + } + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "basic", + "ext": { + "customParams": { + "foo": "bar" + } + } + }, + { + "id": "imp-empty-custom", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "empty-custom", + "ext": {} + }, + { + "id": "imp-nested-custom", + "banner": { + "format": [ + { + "w": 970, + "h": 250 + } + ] + }, + "tagid": "nested", + "ext": { + "customParams": { + "placement": { + "position": "top", + "sticky": true + }, + "sizes": [ + "970x250", + "728x90" + ] + } + } + } + ] + }, + "impIDs": [ + "imp-basic", + "imp-empty-custom", + "imp-nested-custom" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-basic-1", + "impid": "imp-basic", + "price": 1.25, + "adm": "
Banner 728x90
", + "crid": "crid-basic-1", + "mtype": 1 + }, + { + "id": "bid-empty-1", + "impid": "imp-empty-custom", + "price": 0.75, + "adm": "
Banner 300x250
", + "crid": "crid-empty-1", + "mtype": 1 + }, + { + "id": "bid-nested-1", + "impid": "imp-nested-custom", + "price": 2.5, + "adm": "
Banner 970x250
", + "crid": "crid-nested-1", + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-basic-1", + "impid": "imp-basic", + "price": 1.25, + "adm": "
Banner 728x90
", + "crid": "crid-basic-1", + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "bid-empty-1", + "impid": "imp-empty-custom", + "price": 0.75, + "adm": "
Banner 300x250
", + "crid": "crid-empty-1", + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "bid-nested-1", + "impid": "imp-nested-custom", + "price": 2.5, + "adm": "
Banner 970x250
", + "crid": "crid-nested-1", + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/site-domain-empty-mutation.json b/adapters/rtbstack/rtbstacktest/exemplary/site-domain-empty-mutation.json new file mode 100644 index 0000000000..4339d77473 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/site-domain-empty-mutation.json @@ -0,0 +1,70 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "basic", + "customParams": { + "foo": "bar" + } + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "basic", + "ext": { + "customParams": { + "foo": "bar" + } + } + } + ] + }, + "impIDs": [ + "imp-basic" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/site-domain-fallback.json b/adapters/rtbstack/rtbstacktest/exemplary/site-domain-fallback.json new file mode 100644 index 0000000000..fd198b1bc2 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/site-domain-fallback.json @@ -0,0 +1,100 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "not-a-url", + "domain": "" + }, + "imp": [ + { + "id": "imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "test-tag" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "not-a-url", + "domain": "not-a-url" + }, + "imp": [ + { + "id": "imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "test-tag", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-banner" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-1", + "impid": "imp-banner", + "price": 1.0, + "adm": "
Banner
", + "crid": "crid-1", + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "imp-banner", + "price": 1.0, + "adm": "
Banner
", + "crid": "crid-1", + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/site-domain-mutation.json b/adapters/rtbstack/rtbstacktest/exemplary/site-domain-mutation.json new file mode 100644 index 0000000000..89954b712a --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/site-domain-mutation.json @@ -0,0 +1,71 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://not-empty.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "basic", + "customParams": { + "foo": "bar" + } + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://not-empty.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "basic", + "ext": { + "customParams": { + "foo": "bar" + } + } + } + ] + }, + "impIDs": [ + "imp-basic" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/site-native.json b/adapters/rtbstack/rtbstacktest/exemplary/site-native.json new file mode 100644 index 0000000000..9d4b018203 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/site-native.json @@ -0,0 +1,148 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-site-native-small", + "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\":50}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":120,\"hmin\":120,\"mimes\":[\"image/jpeg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":100}}]}" + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "site-native-small", + "customParams": { + "foo": "bar" + } + } + } + }, + { + "id": "imp-site-native-large", + "native": { + "ver": "1.1", + "request": "{\"ver\":\"1.0\",\"layout\":2,\"adunit\":2,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":300,\"hmin\":300,\"mimes\":[\"image/jpeg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":150}}]}" + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "site-native-large", + "customParams": {} + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-site-native-small", + "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\":50}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":120,\"hmin\":120,\"mimes\":[\"image/jpeg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":100}}]}" + }, + "tagid": "site-native-small", + "ext": { + "customParams": { + "foo": "bar" + } + } + }, + { + "id": "imp-site-native-large", + "native": { + "ver": "1.1", + "request": "{\"ver\":\"1.0\",\"layout\":2,\"adunit\":2,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":300,\"hmin\":300,\"mimes\":[\"image/jpeg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":150}}]}" + }, + "tagid": "site-native-large", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-site-native-small", + "imp-site-native-large" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-site-native-small-1", + "impid": "imp-site-native-small", + "price": 1.5, + "adm": "{\"native\":{\"assets\":[{\"id\":1,\"title\":{\"text\":\"Small Native Ad\"}}]}}", + "crid": "crid-site-native-small-1", + "mtype": 4 + }, + { + "id": "bid-site-native-large-1", + "impid": "imp-site-native-large", + "price": 2.75, + "adm": "{\"native\":{\"assets\":[{\"id\":1,\"title\":{\"text\":\"Large Native Ad\"}}]}}", + "crid": "crid-site-native-large-1", + "mtype": 4 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-site-native-small-1", + "impid": "imp-site-native-small", + "price": 1.5, + "adm": "{\"native\":{\"assets\":[{\"id\":1,\"title\":{\"text\":\"Small Native Ad\"}}]}}", + "crid": "crid-site-native-small-1", + "mtype": 4 + }, + "type": "native" + }, + { + "bid": { + "id": "bid-site-native-large-1", + "impid": "imp-site-native-large", + "price": 2.75, + "adm": "{\"native\":{\"assets\":[{\"id\":1,\"title\":{\"text\":\"Large Native Ad\"}}]}}", + "crid": "crid-site-native-large-1", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/site-region-eu.json b/adapters/rtbstack/rtbstacktest/exemplary/site-region-eu.json new file mode 100644 index 0000000000..c027397c7f --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/site-region-eu.json @@ -0,0 +1,107 @@ +{ + "mockBidRequest": { + "id": "test-request-eu", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-eu-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://publisher.eu-adx-admixer.rtb-stack.com/prebid?client=a1b2c3d4-e5f6-7890-abcd-ef1234567890&endpoint=500&ssp=200", + "tagId": "eu-banner", + "customParams": { + "geo": "europe" + } + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://eu-adx-admixer.rtb-stack.com/pbs?ssp=200&endpoint=500&client=a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "body": { + "id": "test-request-eu", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-eu-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "eu-banner", + "ext": { + "customParams": { + "geo": "europe" + } + } + } + ] + }, + "impIDs": [ + "imp-eu-banner" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-eu", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-eu-1", + "impid": "imp-eu-banner", + "price": 1.1, + "adm": "
EU Banner 300x250
", + "crid": "crid-eu-1", + "mtype": 1 + } + ] + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "bid-eu-1", + "impid": "imp-eu-banner", + "price": 1.1, + "adm": "
EU Banner 300x250
", + "crid": "crid-eu-1", + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/site-region-sg.json b/adapters/rtbstack/rtbstacktest/exemplary/site-region-sg.json new file mode 100644 index 0000000000..7c685fe00a --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/site-region-sg.json @@ -0,0 +1,113 @@ +{ + "mockBidRequest": { + "id": "test-request-sg", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-sg-video", + "video": { + "w": 640, + "h": 360, + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ] + }, + "ext": { + "bidder": { + "route": "https://mysite.sg-adx-admixer.rtb-stack.com/prebid?client=f9e8d7c6-b5a4-3210-fedc-ba0987654321&endpoint=777&ssp=88", + "tagId": "sg-video", + "customParams": { + "geo": "asia" + } + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://sg-adx-admixer.rtb-stack.com/pbs?ssp=88&endpoint=777&client=f9e8d7c6-b5a4-3210-fedc-ba0987654321", + "body": { + "id": "test-request-sg", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-sg-video", + "video": { + "w": 640, + "h": 360, + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ] + }, + "tagid": "sg-video", + "ext": { + "customParams": { + "geo": "asia" + } + } + } + ] + }, + "impIDs": [ + "imp-sg-video" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-sg", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-sg-1", + "impid": "imp-sg-video", + "price": 4.5, + "adm": "SG Video Ad", + "crid": "crid-sg-1", + "mtype": 2 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-sg-1", + "impid": "imp-sg-video", + "price": 4.5, + "adm": "SG Video Ad", + "crid": "crid-sg-1", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/exemplary/site-video.json b/adapters/rtbstack/rtbstacktest/exemplary/site-video.json new file mode 100644 index 0000000000..6d3f1aeefe --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/exemplary/site-video.json @@ -0,0 +1,184 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-video-small", + "video": { + "w": 640, + "h": 360, + "mimes": [ + "video/mp4", + "video/webm" + ], + "minduration": 5, + "maxduration": 30, + "protocols": [ + 2, + 5 + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "video-small", + "customParams": { + "foo": "bar" + } + } + } + }, + { + "id": "imp-video-large", + "video": { + "w": 1280, + "h": 720, + "mimes": [ + "video/mp4", + "video/webm" + ], + "minduration": 10, + "maxduration": 60, + "protocols": [ + 2, + 5, + 6 + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "video-large", + "customParams": {} + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-video-small", + "video": { + "w": 640, + "h": 360, + "mimes": [ + "video/mp4", + "video/webm" + ], + "minduration": 5, + "maxduration": 30, + "protocols": [ + 2, + 5 + ] + }, + "tagid": "video-small", + "ext": { + "customParams": { + "foo": "bar" + } + } + }, + { + "id": "imp-video-large", + "video": { + "w": 1280, + "h": 720, + "mimes": [ + "video/mp4", + "video/webm" + ], + "minduration": 10, + "maxduration": 60, + "protocols": [ + 2, + 5, + 6 + ] + }, + "tagid": "video-large", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-video-small", + "imp-video-large" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-video-small-1", + "impid": "imp-video-small", + "price": 3.0, + "adm": "Small Video Ad", + "crid": "crid-video-small-1", + "mtype": 2 + }, + { + "id": "bid-video-large-1", + "impid": "imp-video-large", + "price": 5.5, + "adm": "Large Video Ad", + "crid": "crid-video-large-1", + "mtype": 2 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-video-small-1", + "impid": "imp-video-small", + "price": 3.0, + "adm": "Small Video Ad", + "crid": "crid-video-small-1", + "mtype": 2 + }, + "type": "video" + }, + { + "bid": { + "id": "bid-video-large-1", + "impid": "imp-video-large", + "price": 5.5, + "adm": "Large Video Ad", + "crid": "crid-video-large-1", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/supplemental/bad-bidder-ext.json b/adapters/rtbstack/rtbstacktest/supplemental/bad-bidder-ext.json new file mode 100644 index 0000000000..5d3c2f4509 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/supplemental/bad-bidder-ext.json @@ -0,0 +1,27 @@ +{ + "mockBidRequest": { + "id": "test-request-bad-bidder-ext", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-bad-ext", + "banner": { + "format": [{ "w": 300, "h": 250 }] + }, + "ext": { + "bidder": "not-an-object" + } + } + ] + }, + + "expectedMakeRequestsErrors": [ + { + "value": "Wrong RTBStack bidder ext", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/supplemental/bad-imp.json b/adapters/rtbstack/rtbstacktest/supplemental/bad-imp.json new file mode 100644 index 0000000000..7fb55166c3 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/supplemental/bad-imp.json @@ -0,0 +1,29 @@ +{ + "mockBidRequest": { + "id": "test-request-error", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-invalid", + "banner": { + "format": [{ "w": 300, "h": 250 }] + }, + "ext": "invalid-json" + } + ] + }, + + "httpCalls": [], + + "expectedMakeRequestsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ], + + "expectedBidResponses": [] +} diff --git a/adapters/rtbstack/rtbstacktest/supplemental/bad-mtype.json b/adapters/rtbstack/rtbstacktest/supplemental/bad-mtype.json new file mode 100644 index 0000000000..2b79830d11 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/supplemental/bad-mtype.json @@ -0,0 +1,94 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "test-tag" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "test-tag", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-banner" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-1", + "impid": "imp-banner", + "price": 1.0, + "adm": "
Banner
", + "crid": "crid-1", + "mtype": 0 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unsupported MType 0 for bid imp-banner", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/supplemental/bad-response.json b/adapters/rtbstack/rtbstacktest/supplemental/bad-response.json new file mode 100644 index 0000000000..2901ee1359 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/supplemental/bad-response.json @@ -0,0 +1,69 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "test-banner", + "customParams": { + "foo": "bar" + } + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "test-banner", + "ext": { + "customParams": { + "foo": "bar" + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": "{\"id\"data.lost" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/supplemental/bad-route-invalid-region.json b/adapters/rtbstack/rtbstacktest/supplemental/bad-route-invalid-region.json new file mode 100644 index 0000000000..156148b2cd --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/supplemental/bad-route-invalid-region.json @@ -0,0 +1,30 @@ +{ + "mockBidRequest": { + "id": "test-request-bad-region", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-bad-region", + "banner": { + "format": [{ "w": 300, "h": 250 }] + }, + "ext": { + "bidder": { + "route": "https://publisher.xx-adx-admixer.rtb-stack.com/prebid?client=abc&endpoint=1&ssp=2", + "tagId": "test-tag" + } + } + } + ] + }, + + "expectedMakeRequestsErrors": [ + { + "value": "unable to extract valid region from route URL hostname", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/supplemental/bad-route-missing-params.json b/adapters/rtbstack/rtbstacktest/supplemental/bad-route-missing-params.json new file mode 100644 index 0000000000..ad6a6a463d --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/supplemental/bad-route-missing-params.json @@ -0,0 +1,30 @@ +{ + "mockBidRequest": { + "id": "test-request-missing-params", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-missing-params", + "banner": { + "format": [{ "w": 300, "h": 250 }] + }, + "ext": { + "bidder": { + "route": "https://publisher.us-adx-admixer.rtb-stack.com/prebid", + "tagId": "test-tag" + } + } + } + ] + }, + + "expectedMakeRequestsErrors": [ + { + "value": "route URL must contain client, endpoint, and ssp query parameters", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/supplemental/multi-route-partial-failure.json b/adapters/rtbstack/rtbstacktest/supplemental/multi-route-partial-failure.json new file mode 100644 index 0000000000..ebbf7c392d --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/supplemental/multi-route-partial-failure.json @@ -0,0 +1,123 @@ +{ + "mockBidRequest": { + "id": "test-request-mixed-routes", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-good", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "route": "https://publisher.us-adx-admixer.rtb-stack.com/prebid?client=client-good&endpoint=10&ssp=20", + "tagId": "good-tag" + } + } + }, + { + "id": "imp-bad-region", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "route": "https://publisher.xx-adx-admixer.rtb-stack.com/prebid?client=client-bad&endpoint=99&ssp=88", + "tagId": "bad-tag" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=20&endpoint=10&client=client-good", + "body": { + "id": "test-request-mixed-routes", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [ + { + "id": "imp-good", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "good-tag", + "ext": {} + } + ] + }, + "impIDs": [ + "imp-good" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-mixed-routes", + "seatbid": [ + { + "seat": "rtbstack", + "bid": [ + { + "id": "bid-good-1", + "impid": "imp-good", + "price": 1.0, + "adm": "
good
", + "crid": "crid-good-1", + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-good-1", + "impid": "imp-good", + "price": 1.0, + "adm": "
good
", + "crid": "crid-good-1", + "mtype": 1 + }, + "type": "banner" + } + ] + } + ], + "expectedMakeRequestsErrors": [ + { + "value": "unable to extract valid region from route URL hostname", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/supplemental/no-imps.json b/adapters/rtbstack/rtbstacktest/supplemental/no-imps.json new file mode 100644 index 0000000000..74130ada64 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/supplemental/no-imps.json @@ -0,0 +1,17 @@ +{ + "mockBidRequest": { + "id": "test-request-no-imps", + "site": { + "page": "https://example.com", + "domain": "example.com" + }, + "imp": [] + }, + + "expectedMakeRequestsErrors": [ + { + "value": "No impressions in request", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/supplemental/status-204.json b/adapters/rtbstack/rtbstacktest/supplemental/status-204.json new file mode 100644 index 0000000000..49d97f6c63 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/supplemental/status-204.json @@ -0,0 +1,71 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "basic", + "customParams": { + "foo": "bar" + } + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "basic", + "ext": { + "customParams": { + "foo": "bar" + } + } + } + ] + }, + "impIDs": [ + "imp-basic" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/rtbstack/rtbstacktest/supplemental/status-400.json b/adapters/rtbstack/rtbstacktest/supplemental/status-400.json new file mode 100644 index 0000000000..4b8f01fd8a --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/supplemental/status-400.json @@ -0,0 +1,77 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "basic", + "customParams": { + "foo": "bar" + } + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-id", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-basic", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "basic", + "ext": { + "customParams": { + "foo": "bar" + } + } + } + ] + }, + "impIDs": [ + "imp-basic" + ] + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbstack/rtbstacktest/supplemental/two-imps-one-is-bad.json b/adapters/rtbstack/rtbstacktest/supplemental/two-imps-one-is-bad.json new file mode 100644 index 0000000000..04c1d35d98 --- /dev/null +++ b/adapters/rtbstack/rtbstacktest/supplemental/two-imps-one-is-bad.json @@ -0,0 +1,89 @@ +{ + "mockBidRequest": { + "id": "test-request-partial", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-valid", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "route": "https://testsite.us-adx-admixer.rtb-stack.com/prebid?client=c4527281-5aa5-4c8e-bc53-a80bb3f99470&endpoint=309&ssp=145", + "tagId": "valid-tag", + "customParams": { + "foo": "bar" + } + } + } + }, + { + "id": "imp-invalid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": "invalid-json" + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://us-adx-admixer.rtb-stack.com/pbs?ssp=145&endpoint=309&client=c4527281-5aa5-4c8e-bc53-a80bb3f99470", + "body": { + "id": "test-request-partial", + "site": { + "page": "https://example.com", + "domain": "https://example.com" + }, + "imp": [ + { + "id": "imp-valid", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "valid-tag", + "ext": { + "customParams": { + "foo": "bar" + } + } + } + ] + }, + "impIDs": [ + "imp-valid" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedMakeRequestsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/rubicon/rubicon.go b/adapters/rubicon/rubicon.go index b0a694905a..efcde7037c 100644 --- a/adapters/rubicon/rubicon.go +++ b/adapters/rubicon/rubicon.go @@ -8,14 +8,14 @@ import ( "strconv" "strings" - "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/prebid/prebid-server/v4/version" + + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/maputil" "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" diff --git a/adapters/rubicon/rubicon_test.go b/adapters/rubicon/rubicon_test.go index 3e26e2db12..fe9f079c00 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/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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/adcom1" diff --git a/adapters/sa_lunamedia/params_test.go b/adapters/sa_lunamedia/params_test.go index 640af6ceb3..1ad6ccf3fd 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/sa_lunamedia/salunamedia.go b/adapters/sa_lunamedia/salunamedia.go index b75ccd9f8a..69b19d9fcd 100644 --- a/adapters/sa_lunamedia/salunamedia.go +++ b/adapters/sa_lunamedia/salunamedia.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/sa_lunamedia/salunamedia_test.go b/adapters/sa_lunamedia/salunamedia_test.go index 3247bb0a57..953bbca6e0 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/screencore/params_test.go b/adapters/scalibur/params_test.go similarity index 58% rename from adapters/screencore/params_test.go rename to adapters/scalibur/params_test.go index 508731fbde..994a8fb23b 100644 --- a/adapters/screencore/params_test.go +++ b/adapters/scalibur/params_test.go @@ -1,16 +1,12 @@ -package screencore +package scalibur import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) -var validParams = []string{ - `{ "accountId": "hash", "placementId": "hash"}`, -} - func TestValidParams(t *testing.T) { validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") if err != nil { @@ -18,24 +14,12 @@ func TestValidParams(t *testing.T) { } for _, validParam := range validParams { - if err := validator.Validate(openrtb_ext.BidderScreencore, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected Screencore params: %s", validParam) + if err := validator.Validate(openrtb_ext.BidderScalibur, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected scalibur params: %s", validParam) } } } -var invalidParams = []string{ - ``, - `null`, - `true`, - `5`, - `5.2`, - `[]`, - `{}`, - `{"adCode": "string", "seatCode": 5, "originalPublisherid": "string"}`, - `{ "placementId": "", "accountId": "" }`, -} - func TestInvalidParams(t *testing.T) { validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") if err != nil { @@ -43,8 +27,25 @@ func TestInvalidParams(t *testing.T) { } for _, invalidParam := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderScreencore, json.RawMessage(invalidParam)); err == nil { + if err := validator.Validate(openrtb_ext.BidderScalibur, json.RawMessage(invalidParam)); err == nil { t.Errorf("Schema allowed unexpected params: %s", invalidParam) } } } + +var validParams = []string{ + `{"placementId":"p123"}`, + `{"placementId":"p123", "bidfloor": 1.5}`, + `{"placementId":"p123", "bidfloor": 1.5, "bidfloorcur": "USD"}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `[]`, + `{}`, + `{"placementId": 123}`, + `{"bidfloor": 1.5}`, +} diff --git a/adapters/scalibur/scalibur.go b/adapters/scalibur/scalibur.go new file mode 100644 index 0000000000..f4c77ffa5b --- /dev/null +++ b/adapters/scalibur/scalibur.go @@ -0,0 +1,320 @@ +package scalibur + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v20/adcom1" + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint *template.Template +} + +// Builder builds a new instance of the Scalibur adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + temp, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + return &adapter{ + endpoint: temp, + }, nil +} + +// MakeRequests creates the HTTP requests which should be made to fetch bids from Scalibur. +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var errs []error + var validImps []openrtb2.Imp + + // Process each impression + for _, imp := range request.Imp { + scaliburExt, err := parseScaliburExt(imp.Ext) + if err != nil { + errs = append(errs, err) + continue + } + + impCopy := imp + + // Apply bid floor and currency + if scaliburExt.BidFloor != nil && *scaliburExt.BidFloor > 0 { + impCopy.BidFloor = *scaliburExt.BidFloor + if scaliburExt.BidFloorCur != "" { + impCopy.BidFloorCur = scaliburExt.BidFloorCur + } + } + + if impCopy.BidFloor > 0 && impCopy.BidFloorCur != "" && impCopy.BidFloorCur != "USD" { + convertedValue, err := reqInfo.ConvertCurrency(impCopy.BidFloor, impCopy.BidFloorCur, "USD") + if err != nil { + errs = append(errs, err) + continue + } + impCopy.BidFloor = convertedValue + impCopy.BidFloorCur = "USD" + } + + if impCopy.BidFloorCur == "" { + impCopy.BidFloorCur = "USD" + } + + // Prepare imp.ext with placementId and params + impExtData := make(map[string]interface{}) + impExtData["placementId"] = scaliburExt.PlacementID + + if impCopy.BidFloor > 0 { + impExtData["bidfloor"] = impCopy.BidFloor + } + impExtData["bidfloorcur"] = impCopy.BidFloorCur + + // Preserve GPID if present + var rawExt map[string]json.RawMessage + if err := jsonutil.Unmarshal(imp.Ext, &rawExt); err == nil { + if gpid, ok := rawExt["gpid"]; ok { + impExtData["gpid"] = json.RawMessage(gpid) + } + } + + impExt, err := jsonutil.Marshal(impExtData) + if err != nil { + errs = append(errs, err) + continue + } + impCopy.Ext = impExt + + // Apply video defaults (matching JS defaults) + if impCopy.Video != nil { + videoCopy := *impCopy.Video + + // Note: In openrtb v20, field names are capitalized (MIMEs not Mimes) + if len(videoCopy.MIMEs) == 0 { + videoCopy.MIMEs = []string{"video/mp4"} + } + if videoCopy.MinDuration == 0 { + videoCopy.MinDuration = 1 + } + if videoCopy.MaxDuration == 0 { + videoCopy.MaxDuration = 180 + } + if videoCopy.MaxBitRate == 0 { + videoCopy.MaxBitRate = 30000 + } + if len(videoCopy.Protocols) == 0 { + // Use adcom1.MediaCreativeSubtype for protocols in v20 + videoCopy.Protocols = []adcom1.MediaCreativeSubtype{2, 3, 5, 6} + } + // Note: In openrtb v20, W and H are pointers + if videoCopy.W == nil || *videoCopy.W == 0 { + w := int64(640) + videoCopy.W = &w + } + if videoCopy.H == nil || *videoCopy.H == 0 { + h := int64(480) + videoCopy.H = &h + } + if videoCopy.Placement == 0 { + videoCopy.Placement = 1 + } + if videoCopy.Linearity == 0 { + videoCopy.Linearity = 1 + } + + impCopy.Video = &videoCopy + } + + validImps = append(validImps, impCopy) + } + + // If no valid impressions, return errors + if len(validImps) == 0 { + return nil, errs + } + + // Create the outgoing request + requestCopy := *request + requestCopy.Imp = validImps + requestCopy.Cur = nil + + isDebug := request.Test == 1 + if !isDebug && len(request.Ext) > 0 { + var extRequest openrtb_ext.ExtRequest + if err := jsonutil.Unmarshal(request.Ext, &extRequest); err == nil { + isDebug = extRequest.Prebid.Debug + } + } + + if isDebug { + reqExt := openrtb_ext.ExtRequestScalibur{IsDebug: 1} + if reqExtJSON, err := jsonutil.Marshal(reqExt); err == nil { + requestCopy.Ext = reqExtJSON + } + } else { + requestCopy.Ext = nil + } + + reqJSON, err := jsonutil.Marshal(requestCopy) + if err != nil { + return nil, append(errs, err) + } + + var endpointBuffer bytes.Buffer + if err := a.endpoint.Execute(&endpointBuffer, nil); 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: endpointBuffer.String(), + Body: reqJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(requestCopy.Imp), + } + + return []*adapters.RequestData{requestData}, errs +} + +// MakeBids unpacks the server's response into bids. +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if response.StatusCode == http.StatusNoContent { + return nil, nil + } + + if response.StatusCode != http.StatusOK { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), + }} + } + + var bidResp openrtb2.BidResponse + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + // Parse the external request to get impression details + var bidReq openrtb2.BidRequest + if err := jsonutil.Unmarshal(externalRequest.Body, &bidReq); err != nil { + return nil, []error{err} + } + + // Build impression map for lookup + impMap := make(map[string]*openrtb2.Imp, len(bidReq.Imp)) + for i := range bidReq.Imp { + impMap[bidReq.Imp[i].ID] = &bidReq.Imp[i] + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidReq.Imp)) + + // Set currency + if bidResp.Cur != "" { + bidResponse.Currency = bidResp.Cur + } else { + bidResponse.Currency = "USD" + } + + // Process each seat bid + for _, seatBid := range bidResp.SeatBid { + for _, bid := range seatBid.Bid { + // Find the corresponding imp + imp, found := impMap[bid.ImpID] + if !found { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("Invalid bid imp ID %s", bid.ImpID), + }} + } + + // Determine bid type based on imp + bidType, err := getBidMediaType(bid, imp) + if err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: err.Error(), + }} + } + + bidCopy := bid + + // Handle video VAST + if bidType == openrtb_ext.BidTypeVideo { + // Try to extract custom fields vastXml and vastUrl from bid.ext + var bidExtData struct { + VastXML string `json:"vastXml"` + VastURL string `json:"vastUrl"` + } + if bid.Ext != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExtData); err == nil { + if bidExtData.VastXML != "" { + bidCopy.AdM = bidExtData.VastXML + } else if bidExtData.VastURL != "" && bidCopy.AdM == "" { + // Wrap VAST URL in VAST wrapper + bidCopy.AdM = fmt.Sprintf(``, bidExtData.VastURL) + } + } + } + } + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &bidCopy, + BidType: bidType, + }) + } + } + + if len(bidResponse.Bids) == 0 { + return nil, nil + } + + return bidResponse, nil +} + +// parseScaliburExt extracts Scalibur-specific parameters from the impression extension. +func parseScaliburExt(impExt json.RawMessage) (*openrtb_ext.ExtImpScalibur, error) { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(impExt, &bidderExt); err != nil { + return nil, &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to parse imp.ext: %s", err.Error()), + } + } + + var scaliburExt openrtb_ext.ExtImpScalibur + if err := jsonutil.Unmarshal(bidderExt.Bidder, &scaliburExt); err != nil { + return nil, &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to parse Scalibur params: %s", err.Error()), + } + } + + return &scaliburExt, nil +} + +// getBidMediaType determines the media type based on the impression +func getBidMediaType(bid openrtb2.Bid, imp *openrtb2.Imp) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + } + + // Fallback for bidders not supporting mtype (non-multi-format requests) + if imp.Banner != nil && imp.Video == nil { + return openrtb_ext.BidTypeBanner, nil + } + if imp.Video != nil && imp.Banner == nil { + return openrtb_ext.BidTypeVideo, nil + } + + return "", fmt.Errorf("unsupported or ambiguous media type for bid id=%s", bid.ID) +} diff --git a/adapters/scalibur/scalibur_test.go b/adapters/scalibur/scalibur_test.go new file mode 100644 index 0000000000..3199e8ef66 --- /dev/null +++ b/adapters/scalibur/scalibur_test.go @@ -0,0 +1,344 @@ +package scalibur + +import ( + "encoding/json" + "net/http" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func newTestAdapter() adapters.Bidder { + adapter, _ := Builder( + openrtb_ext.BidderScalibur, + config.Adapter{Endpoint: "https://srv.scalibur.io/adserver/ortb?type=prebid-server"}, + config.Server{}, + ) + return adapter +} + +// +// ------------------------------------------------------------------------------------------ +// MAKE REQUESTS TESTS +// ------------------------------------------------------------------------------------------ +// + +func TestJsonSamples(t *testing.T) { + adapterstest.RunJSONBidderTest(t, "scaliburtest", newTestAdapter()) +} + +func TestMakeRequests_SuccessBanner(t *testing.T) { + bidder := newTestAdapter() + + ext, _ := json.Marshal(adapters.ExtImpBidder{ + Bidder: json.RawMessage(`{ + "placementId": "p123", + "bidfloor": 1.25, + "bidfloorcur": "EUR" + }`), + }) + + req := &openrtb2.BidRequest{ + ID: "req1", + Imp: []openrtb2.Imp{ + { + ID: "imp1", + Ext: ext, + Banner: &openrtb2.Banner{ + W: ptrInt64(300), H: ptrInt64(250), + }, + }, + }, + Site: &openrtb2.Site{Page: "https://test.com"}, + } + + requests, errs := bidder.MakeRequests(req, &adapters.ExtraRequestInfo{ + CurrencyConversions: &mockConversions{}, + }) + + require.Len(t, errs, 0) + require.Len(t, requests, 1) + + r := requests[0] + assert.Equal(t, "https://srv.scalibur.io/adserver/ortb?type=prebid-server", r.Uri) + assert.Equal(t, "POST", r.Method) + assert.Contains(t, r.Headers.Get("Content-Type"), "application/json") + + // Ensure body contains rewritten ext fields + var out openrtb2.BidRequest + require.NoError(t, json.Unmarshal(r.Body, &out)) + require.Len(t, out.Imp, 1) + + imp := out.Imp[0] + + assert.Equal(t, float64(1.25), imp.BidFloor) + assert.Equal(t, "USD", imp.BidFloorCur) + + var outExt map[string]interface{} + require.NoError(t, json.Unmarshal(imp.Ext, &outExt)) + assert.Equal(t, "p123", outExt["placementId"]) +} + +func TestMakeRequests_InvalidExt(t *testing.T) { + bidder := newTestAdapter() + + badExt, _ := json.Marshal(adapters.ExtImpBidder{ + Bidder: json.RawMessage(`{invalid`), + }) + + req := &openrtb2.BidRequest{ + ID: "req2", + Imp: []openrtb2.Imp{ + { + ID: "imp1", + Ext: badExt, + Banner: &openrtb2.Banner{ + W: ptrInt64(300), H: ptrInt64(250), + }, + }, + }, + } + + requests, errs := bidder.MakeRequests(req, &adapters.ExtraRequestInfo{}) + + require.Len(t, requests, 0) + require.Len(t, errs, 1) + assert.Contains(t, errs[0].Error(), "Failed to parse imp.ext") +} + +func TestMakeRequests_VideoDefaultsApplied(t *testing.T) { + bidder := newTestAdapter() + + ext, _ := json.Marshal(adapters.ExtImpBidder{ + Bidder: json.RawMessage(`{"placementId": "p123"}`), + }) + + req := &openrtb2.BidRequest{ + ID: "req-video", + Imp: []openrtb2.Imp{ + { + ID: "v1", + Ext: ext, + Video: &openrtb2.Video{ + // Intentionally empty → should fill defaults + }, + }, + }, + } + + requests, errs := bidder.MakeRequests(req, &adapters.ExtraRequestInfo{ + CurrencyConversions: &mockConversions{}, + }) + + require.Len(t, errs, 0) + require.Len(t, requests, 1) + + var out openrtb2.BidRequest + require.NoError(t, json.Unmarshal(requests[0].Body, &out)) + + v := out.Imp[0].Video + require.NotNil(t, v) + + assert.NotEmpty(t, v.MIMEs) + assert.NotZero(t, v.MinDuration) + assert.NotZero(t, v.MaxDuration) + assert.NotZero(t, v.MaxBitRate) + assert.NotEmpty(t, v.Protocols) + assert.NotNil(t, v.W) + assert.NotNil(t, v.H) + assert.NotZero(t, v.Placement) + assert.NotZero(t, v.Linearity) +} + +type mockConversions struct{} + +func (m *mockConversions) GetRate(from string, to string) (float64, error) { + return 1.0, nil +} + +func (m *mockConversions) GetRates() *map[string]map[string]float64 { + return nil +} + +// +// ------------------------------------------------------------------------------------------ +// MAKE BIDS TESTS +// ------------------------------------------------------------------------------------------ +// + +func TestMakeBids_SuccessBanner(t *testing.T) { + bidder := newTestAdapter() + + mockReq := &openrtb2.BidRequest{ + ID: "req1", + Imp: []openrtb2.Imp{ + { + ID: "1", + Banner: &openrtb2.Banner{W: ptrInt64(300), H: ptrInt64(250)}, + }, + }, + } + + mockReqData := &adapters.RequestData{ + Body: func() []byte { + b, _ := json.Marshal(mockReq) + return b + }(), + } + + mockResp := &openrtb2.BidResponse{ + ID: "resp1", + Cur: "USD", + SeatBid: []openrtb2.SeatBid{ + { + Bid: []openrtb2.Bid{ + { + ID: "b1", + ImpID: "1", + Price: 2.5, + AdM: "
ad markup
", + W: 300, + H: 250, + }, + }, + }, + }, + } + + respData := &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: func() []byte { + b, _ := json.Marshal(mockResp) + return b + }(), + } + + bidderResp, errs := bidder.MakeBids(mockReq, mockReqData, respData) + + require.Len(t, errs, 0) + require.NotNil(t, bidderResp) + require.Len(t, bidderResp.Bids, 1) + + b := bidderResp.Bids[0] + assert.Equal(t, openrtb_ext.BidTypeBanner, b.BidType) + assert.Equal(t, float64(2.5), b.Bid.Price) + assert.Equal(t, "
ad markup
", b.Bid.AdM) +} + +func TestMakeBids_EmptySeatBid(t *testing.T) { + bidder := newTestAdapter() + + mockReq := &openrtb2.BidRequest{ + ID: "req2", + Imp: []openrtb2.Imp{}, + } + + mockReqData := &adapters.RequestData{ + Body: []byte(`{"id":"req2","imp":[]}`), + } + + respData := &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{"id":"resp","seatbid":[]}`), + } + + bidderResp, errs := bidder.MakeBids(mockReq, mockReqData, respData) + + require.Len(t, errs, 0) + assert.Nil(t, bidderResp) +} + +func TestMakeBids_Status204(t *testing.T) { + bidder := newTestAdapter() + + respData := &adapters.ResponseData{ + StatusCode: http.StatusNoContent, + } + + resp, errs := bidder.MakeBids(&openrtb2.BidRequest{}, &adapters.RequestData{}, respData) + + assert.Nil(t, resp) + assert.Nil(t, errs) +} + +func TestMakeBids_InvalidJSON(t *testing.T) { + bidder := newTestAdapter() + + respData := &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`not-json`), + } + + _, errs := bidder.MakeBids(&openrtb2.BidRequest{}, &adapters.RequestData{}, respData) + require.Len(t, errs, 1) +} + +func TestMakeBids_ImpNotFound(t *testing.T) { + bidder := newTestAdapter() + + mockReq := &openrtb2.BidRequest{ + ID: "req1", + Imp: []openrtb2.Imp{ + {ID: "1"}, + }, + } + + mockReqData := &adapters.RequestData{ + Body: []byte(`{"id":"req1","imp":[{"id":"1"}]}`), + } + + mockResp := &openrtb2.BidResponse{ + ID: "resp1", + SeatBid: []openrtb2.SeatBid{ + { + Bid: []openrtb2.Bid{ + { + ID: "b1", + ImpID: "non-existent", + }, + }, + }, + }, + } + + respData := &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: func() []byte { + b, _ := json.Marshal(mockResp) + return b + }(), + } + + _, errs := bidder.MakeBids(mockReq, mockReqData, respData) + require.Len(t, errs, 1) + assert.Contains(t, errs[0].Error(), "Invalid bid imp ID non-existent") +} + +func TestGetBidMediaType_Error(t *testing.T) { + bid := openrtb2.Bid{ + ID: "bid1", + ImpID: "imp1", + } + imp := &openrtb2.Imp{ + ID: "imp1", + // No banner or video + } + + _, err := getBidMediaType(bid, imp) + assert.Error(t, err) + assert.Contains(t, err.Error(), "unsupported or ambiguous media type") +} + +func TestParseScaliburExt_ErrorCases(t *testing.T) { + _, err := parseScaliburExt(json.RawMessage(`{invalid`)) + assert.Error(t, err) + assert.Contains(t, err.Error(), "Failed to parse imp.ext") +} + +func ptrInt64(x int64) *int64 { return &x } diff --git a/adapters/scalibur/scaliburtest/exemplary/bid-floor-eur-to-usd.json b/adapters/scalibur/scaliburtest/exemplary/bid-floor-eur-to-usd.json new file mode 100644 index 0000000000..c9d3b37c39 --- /dev/null +++ b/adapters/scalibur/scaliburtest/exemplary/bid-floor-eur-to-usd.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "ext": { + "bidder": { + "placementId": "test-scl-placement", + "bidfloor": 1.0, + "bidfloorcur": "EUR" + } + } + }], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 1.2 + } + } + } + } + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://srv.scalibur.io/adserver/ortb?type=prebid-server", + "impIDs": ["test-imp-id"], + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "bidfloor": 1.2, + "bidfloorcur": "USD", + "ext": { + "placementId": "test-scl-placement", + "bidfloor": 1.2, + "bidfloorcur": "USD" + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.2, + "adm": "...", + "crid": "test-creative-id", + "w": 300, + "h": 250 + }] + }], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.2, + "adm": "...", + "crid": "test-creative-id", + "w": 300, + "h": 250 + }, + "type": "banner" + }] + }] +} \ No newline at end of file diff --git a/adapters/scalibur/scaliburtest/exemplary/bid-floor-usd.json b/adapters/scalibur/scaliburtest/exemplary/bid-floor-usd.json new file mode 100644 index 0000000000..2549a4d7e0 --- /dev/null +++ b/adapters/scalibur/scaliburtest/exemplary/bid-floor-usd.json @@ -0,0 +1,69 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "ext": { + "bidder": { + "placementId": "test-scl-placement", + "bidfloor": 1.5, + "bidfloorcur": "USD" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://srv.scalibur.io/adserver/ortb?type=prebid-server", + "impIDs": ["test-imp-id"], + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "bidfloor": 1.5, + "bidfloorcur": "USD", + "ext": { + "placementId": "test-scl-placement", + "bidfloor": 1.5, + "bidfloorcur": "USD" + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "...", + "crid": "test-creative-id", + "w": 300, + "h": 250 + }] + }], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "...", + "crid": "test-creative-id", + "w": 300, + "h": 250 + }, + "type": "banner" + }] + }] +} \ No newline at end of file diff --git a/adapters/scalibur/scaliburtest/exemplary/debug.json b/adapters/scalibur/scaliburtest/exemplary/debug.json new file mode 100644 index 0000000000..4422ffb07e --- /dev/null +++ b/adapters/scalibur/scaliburtest/exemplary/debug.json @@ -0,0 +1,59 @@ +{ + "mockBidRequest": { + "id": "test-debug-request", + "test": 1, + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "ext": { "bidder": { "placementId": "test-placement" } } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://srv.scalibur.io/adserver/ortb?type=prebid-server", + "impIDs": ["test-imp-id"], + "body": { + "id": "test-debug-request", + "test": 1, + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "bidfloorcur": "USD", + "ext": { + "placementId": "test-placement", + "bidfloorcur": "USD" + } + }], + "ext": { "isDebug": 1 } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-debug-request", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id" + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id" + }, + "type": "banner" + }] + }] +} diff --git a/adapters/scalibur/scaliburtest/exemplary/debug_prebid.json b/adapters/scalibur/scaliburtest/exemplary/debug_prebid.json new file mode 100644 index 0000000000..5f780c6810 --- /dev/null +++ b/adapters/scalibur/scaliburtest/exemplary/debug_prebid.json @@ -0,0 +1,62 @@ +{ + "mockBidRequest": { + "id": "test-debug-prebid-request", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "ext": { "bidder": { "placementId": "test-placement" } } + }], + "ext": { + "prebid": { + "debug": true + } + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://srv.scalibur.io/adserver/ortb?type=prebid-server", + "impIDs": ["test-imp-id"], + "body": { + "id": "test-debug-prebid-request", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "bidfloorcur": "USD", + "ext": { + "placementId": "test-placement", + "bidfloorcur": "USD" + } + }], + "ext": { "isDebug": 1 } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-debug-prebid-request", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id" + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id" + }, + "type": "banner" + }] + }] +} diff --git a/adapters/scalibur/scaliburtest/exemplary/gpid.json b/adapters/scalibur/scaliburtest/exemplary/gpid.json new file mode 100644 index 0000000000..393c8a86dd --- /dev/null +++ b/adapters/scalibur/scaliburtest/exemplary/gpid.json @@ -0,0 +1,65 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "ext": { + "bidder": { "placementId": "test-scl-placement" }, + "gpid": "test-gpid-value" + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://srv.scalibur.io/adserver/ortb?type=prebid-server", + "impIDs": ["test-imp-id"], + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "bidfloorcur": "USD", + "ext": { + "placementId": "test-scl-placement", + "bidfloorcur": "USD", + "gpid": "test-gpid-value" + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id", + "w": 300, + "h": 250 + }] + }], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id", + "w": 300, + "h": 250 + }, + "type": "banner" + }] + }] +} diff --git a/adapters/scalibur/scaliburtest/exemplary/mtype.json b/adapters/scalibur/scaliburtest/exemplary/mtype.json new file mode 100644 index 0000000000..4256373d8f --- /dev/null +++ b/adapters/scalibur/scaliburtest/exemplary/mtype.json @@ -0,0 +1,58 @@ +{ + "mockBidRequest": { + "id": "test-mtype-request", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "ext": { "bidder": { "placementId": "test-placement" } } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://srv.scalibur.io/adserver/ortb?type=prebid-server", + "impIDs": ["test-imp-id"], + "body": { + "id": "test-mtype-request", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "bidfloorcur": "USD", + "ext": { + "placementId": "test-placement", + "bidfloorcur": "USD" + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-mtype-request", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id", + "mtype": 1 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id", + "mtype": 1 + }, + "type": "banner" + }] + }] +} diff --git a/adapters/scalibur/scaliburtest/exemplary/mtype_video.json b/adapters/scalibur/scaliburtest/exemplary/mtype_video.json new file mode 100644 index 0000000000..32121a1a08 --- /dev/null +++ b/adapters/scalibur/scaliburtest/exemplary/mtype_video.json @@ -0,0 +1,68 @@ +{ + "mockBidRequest": { + "id": "test-mtype-video-request", + "imp": [{ + "id": "test-imp-id", + "video": { "mimes": ["video/mp4"] }, + "ext": { "bidder": { "placementId": "test-placement" } } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://srv.scalibur.io/adserver/ortb?type=prebid-server", + "impIDs": ["test-imp-id"], + "body": { + "id": "test-mtype-video-request", + "imp": [{ + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 1, + "maxduration": 180, + "maxbitrate": 30000, + "protocols": [2, 3, 5, 6], + "w": 640, + "h": 480, + "placement": 1, + "linearity": 1 + }, + "bidfloorcur": "USD", + "ext": { + "placementId": "test-placement", + "bidfloorcur": "USD" + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-mtype-video-request", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id", + "mtype": 2 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id", + "mtype": 2 + }, + "type": "video" + }] + }] +} diff --git a/adapters/scalibur/scaliburtest/exemplary/success_banner.json b/adapters/scalibur/scaliburtest/exemplary/success_banner.json new file mode 100644 index 0000000000..aabe2beb47 --- /dev/null +++ b/adapters/scalibur/scaliburtest/exemplary/success_banner.json @@ -0,0 +1,61 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "ext": { "bidder": { "placementId": "test-scl-placement" } } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://srv.scalibur.io/adserver/ortb?type=prebid-server", + "impIDs": ["test-imp-id"], + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "bidfloorcur": "USD", + "ext": { + "placementId": "test-scl-placement", + "bidfloorcur": "USD" + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id", + "w": 300, + "h": 250 + }] + }], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "...", + "crid": "test-creative-id", + "w": 300, + "h": 250 + }, + "type": "banner" + }] + }] +} \ No newline at end of file diff --git a/adapters/scalibur/scaliburtest/exemplary/video.json b/adapters/scalibur/scaliburtest/exemplary/video.json new file mode 100644 index 0000000000..7eaea7a289 --- /dev/null +++ b/adapters/scalibur/scaliburtest/exemplary/video.json @@ -0,0 +1,78 @@ +{ + "mockBidRequest": { + "id": "test-video-req", + "imp": [{ + "id": "video-imp-1", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "placementId": "46" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://srv.scalibur.io/adserver/ortb?type=prebid-server", + "impIDs": ["video-imp-1"], + "body": { + "id": "test-video-req", + "imp": [{ + "id": "video-imp-1", + "video": { + "mimes": ["video/mp4"], + "minduration": 1, + "maxduration": 180, + "protocols": [2, 3, 5, 6], + "w": 640, + "h": 480, + "placement": 1, + "linearity": 1, + "maxbitrate": 30000 + }, + "bidfloorcur": "USD", + "ext": { + "placementId": "46", + "bidfloorcur": "USD" + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-video-req", + "seatbid": [{ + "bid": [{ + "id": "bid-v1", + "impid": "video-imp-1", + "price": 1.5, + "crid": "cr-video", + "ext": { + "vastXml": "..." + } + }] + }], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "bid-v1", + "impid": "video-imp-1", + "price": 1.5, + "adm": "...", + "crid": "cr-video", + "ext": { "vastXml": "..." } + }, + "type": "video" + }] + }] +} \ No newline at end of file diff --git a/adapters/scalibur/scaliburtest/exemplary/video_vast_url.json b/adapters/scalibur/scaliburtest/exemplary/video_vast_url.json new file mode 100644 index 0000000000..f00833b95b --- /dev/null +++ b/adapters/scalibur/scaliburtest/exemplary/video_vast_url.json @@ -0,0 +1,67 @@ +{ + "mockBidRequest": { + "id": "test-video-url-req", + "imp": [{ + "id": "video-imp-2", + "video": { "mimes": ["video/mp4"] }, + "ext": { "bidder": { "placementId": "46" } } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://srv.scalibur.io/adserver/ortb?type=prebid-server", + "impIDs": ["video-imp-2"], + "body": { + "id": "test-video-url-req", + "imp": [{ + "id": "video-imp-2", + "video": { + "mimes": ["video/mp4"], + "minduration": 1, + "maxduration": 180, + "protocols": [2, 3, 5, 6], + "w": 640, + "h": 480, + "placement": 1, + "linearity": 1, + "maxbitrate": 30000 + }, + "bidfloorcur": "USD", + "ext": { + "placementId": "46", + "bidfloorcur": "USD" + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-video-url-req", + "seatbid": [{ + "bid": [{ + "id": "bid-v2", + "impid": "video-imp-2", + "price": 2.0, + "ext": { + "vastUrl": "https://cdn.scalibur.io/vast.xml" + } + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "bid-v2", + "impid": "video-imp-2", + "price": 2.0, + "adm": "", + "ext": { "vastUrl": "https://cdn.scalibur.io/vast.xml" } + }, + "type": "video" + }] + }] +} \ No newline at end of file diff --git a/adapters/scalibur/scaliburtest/supplemental/bid-floor-currency-conversion-error.json b/adapters/scalibur/scaliburtest/supplemental/bid-floor-currency-conversion-error.json new file mode 100644 index 0000000000..a154313934 --- /dev/null +++ b/adapters/scalibur/scaliburtest/supplemental/bid-floor-currency-conversion-error.json @@ -0,0 +1,34 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { "format": [{"w": 300, "h": 250}] }, + "ext": { + "bidder": { + "placementId": "test-scl-placement", + "bidfloor": 1.5, + "bidfloorcur": "EUR" + } + } + }], + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 1.3 + } + } + } + } + } + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Currency conversion rate not found: 'EUR' => 'USD'", + "comparison": "literal" + } + ] +} diff --git a/adapters/screencore/screencore.go b/adapters/screencore/screencore.go deleted file mode 100644 index 17dab9084b..0000000000 --- a/adapters/screencore/screencore.go +++ /dev/null @@ -1,178 +0,0 @@ -package screencore - -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) { - if len(openRTBRequest.Imp) == 0 { - return nil, []error{&errortypes.BadInput{ - Message: "Empty Imp array in BidRequest", - }} - } - - screencoreExt, err := getImpressionExt(&openRTBRequest.Imp[0]) - if err != nil { - return nil, []error{err} - } - - openRTBRequest.Imp[0].Ext = nil - - url, err := a.buildEndpointURL(screencoreExt) - 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.ExtScreencore, error) { - var bidderExt adapters.ExtImpBidder - 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 := jsonutil.Unmarshal(bidderExt.Bidder, &screencoreExt); err != nil { - return nil, &errortypes.BadInput{ - Message: "Error parsing bidderExt - " + err.Error(), - } - } - - return &screencoreExt, nil -} - -func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtScreencore) (string, error) { - endpointParams := macros.EndpointTemplateParams{AccountID: params.AccountID, SourceId: params.PlacementID} - return macros.ResolveMacros(a.endpoint, endpointParams) -} - -func checkResponseStatusCodes(response *adapters.ResponseData) error { - if response.StatusCode == http.StatusServiceUnavailable { - return &errortypes.BadServerResponse{ - Message: fmt.Sprintf("Something went wrong Status Code: [ %d ] ", response.StatusCode), - } - } - - return adapters.CheckResponseStatusCodeForErrors(response) -} - -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 - } - - httpStatusError := checkResponseStatusCodes(bidderRawResponse) - if httpStatusError != nil { - return nil, []error{httpStatusError} - } - - 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 := getMediaTypeForImp(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 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 "", fmt.Errorf("unsupported MType %d", bid.MType) - } -} diff --git a/adapters/screencore/screencore_test.go b/adapters/screencore/screencore_test.go deleted file mode 100644 index 2451231fe5..0000000000 --- a/adapters/screencore/screencore_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package screencore - -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.BidderScreencore, config.Adapter{ - Endpoint: "http://h1.screencore.io/?kp={{.AccountID}}&kn={{.SourceId}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "screencoretest", bidder) -} diff --git a/adapters/screencore/screencoretest/exemplary/banner-web.json b/adapters/screencore/screencoretest/exemplary/banner-web.json deleted file mode 100644 index 7e9b12546b..0000000000 --- a/adapters/screencore/screencoretest/exemplary/banner-web.json +++ /dev/null @@ -1,198 +0,0 @@ -{ - "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", - "placementId": "placementId" - } - } - }, - { - "id": "some-impression-id2", - "tagid": "ogTAGID", - "banner": { - "w": 320, - "h": 50 - }, - "ext": { - "bidder": { - "accountId": "accountId", - "placementId": "placementId" - } - } - } - ] - }, - "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://h1.screencore.io/?kp=accountId&kn=placementId", - "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", - "placementId": "placementId" - } - } - } - ], - "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": "screencore" - } - ], - "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/screencore/screencoretest/exemplary/native-app.json b/adapters/screencore/screencoretest/exemplary/native-app.json deleted file mode 100644 index eb85dcbfec..0000000000 --- a/adapters/screencore/screencoretest/exemplary/native-app.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "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", - "placementId": "placementId" - } - } - } - ] - }, - "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://h1.screencore.io/?kp=accountId&kn=placementId", - "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": "screencore" - } - ], - "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/screencore/screencoretest/exemplary/native-web.json b/adapters/screencore/screencoretest/exemplary/native-web.json deleted file mode 100644 index a597611c23..0000000000 --- a/adapters/screencore/screencoretest/exemplary/native-web.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "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", - "placementId": "placementId" - } - } - } - ] - }, - "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://h1.screencore.io/?kp=accountId&kn=placementId", - "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": "screencore" - } - ], - "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/screencore/screencoretest/exemplary/video-app.json b/adapters/screencore/screencoretest/exemplary/video-app.json deleted file mode 100644 index 7a29e5b53d..0000000000 --- a/adapters/screencore/screencoretest/exemplary/video-app.json +++ /dev/null @@ -1,162 +0,0 @@ -{ - "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", - "placementId": "placementId" - } - } - } - ] - }, - "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://h1.screencore.io/?kp=accountId&kn=placementId", - "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": "screencore" - } - ], - "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/screencore/screencoretest/supplemental/bad_media_type.json b/adapters/screencore/screencoretest/supplemental/bad_media_type.json deleted file mode 100644 index b8a3994730..0000000000 --- a/adapters/screencore/screencoretest/supplemental/bad_media_type.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "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", - "placementId": "placementId" - } - } - } - ] - }, - "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://h1.screencore.io/?kp=accountId&kn=placementId", - "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, - "seat": "screencore" - } - ], - "cur": "USD" - } - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "unsupported MType 0", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/empty-imp-array.json b/adapters/screencore/screencoretest/supplemental/empty-imp-array.json deleted file mode 100644 index e19996fbe2..0000000000 --- a/adapters/screencore/screencoretest/supplemental/empty-imp-array.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "expectedMakeRequestsErrors": [ - { - "value": "Empty Imp array in BidRequest", - "comparison": "literal" - } - ], - "mockBidRequest": { - "id": "test-request-id", - "imp": [], - "site": { - "page": "test.com" - } - }, - "httpCalls": [] - } \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/invalid-bidder-ext-object.json b/adapters/screencore/screencoretest/supplemental/invalid-bidder-ext-object.json deleted file mode 100644 index 016fbd4349..0000000000 --- a/adapters/screencore/screencoretest/supplemental/invalid-bidder-ext-object.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "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/screencore/screencoretest/supplemental/invalid-screencore-ext-object.json b/adapters/screencore/screencoretest/supplemental/invalid-screencore-ext-object.json deleted file mode 100644 index 4c3c9d9505..0000000000 --- a/adapters/screencore/screencoretest/supplemental/invalid-screencore-ext-object.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "expectedMakeRequestsErrors": [ - { - "value": "Error parsing screencoreExt - 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": "wrongscreencoreExt" - } - ], - "site": { - "page": "test.com" - } - }, - "httpCalls": [] -} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/status-code-bad-request.json b/adapters/screencore/screencoretest/supplemental/status-code-bad-request.json deleted file mode 100644 index cb2ac212e8..0000000000 --- a/adapters/screencore/screencoretest/supplemental/status-code-bad-request.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "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", - "placementId": "placementId" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", - "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/screencore/screencoretest/supplemental/status-code-no-content.json b/adapters/screencore/screencoretest/supplemental/status-code-no-content.json deleted file mode 100644 index b0315e5703..0000000000 --- a/adapters/screencore/screencoretest/supplemental/status-code-no-content.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "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", - "placementId": "placementId" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", - "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": 204 - } - } - ], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [] -} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/status-code-other-error.json b/adapters/screencore/screencoretest/supplemental/status-code-other-error.json deleted file mode 100644 index d35c8b0fa8..0000000000 --- a/adapters/screencore/screencoretest/supplemental/status-code-other-error.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "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", - "placementId": "placementId" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", - "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/screencore/screencoretest/supplemental/status-code-service-unavailable.json b/adapters/screencore/screencoretest/supplemental/status-code-service-unavailable.json deleted file mode 100644 index f6eb482fa9..0000000000 --- a/adapters/screencore/screencoretest/supplemental/status-code-service-unavailable.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "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", - "placementId": "placementId" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", - "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": 503 - } - } - ], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [ - { - "value": "Something went wrong Status Code: [ 503 ] ", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/seedingAlliance/params_test.go b/adapters/seedingAlliance/params_test.go index 56433b003c..77088c077d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/seedingAlliance/seedingAlliance.go b/adapters/seedingAlliance/seedingAlliance.go index 1e23d4e25a..bc367da19e 100644 --- a/adapters/seedingAlliance/seedingAlliance.go +++ b/adapters/seedingAlliance/seedingAlliance.go @@ -9,12 +9,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/seedingAlliance/seedingAlliance_test.go b/adapters/seedingAlliance/seedingAlliance_test.go index b432d0577f..f5721683d7 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/seedtag/params_test.go b/adapters/seedtag/params_test.go index b93be85dfb..f8a6eff8dd 100644 --- a/adapters/seedtag/params_test.go +++ b/adapters/seedtag/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -35,10 +35,16 @@ func TestInvalidParams(t *testing.T) { var validParams = []string{ `{"adUnitId": "27604970"}`, + `{"publisherId": "abc123", "integrationType": "ronId"}`, } var invalidParams = []string{ `{"adUnitId": 123}`, `{"adUnitId": ""}`, `{}`, + `{"publisherId": "abc123"}`, + `{"integrationType": "ronId"}`, + `{"publisherId": "", "integrationType": "ronId"}`, + `{"publisherId": "abc123", "integrationType": "unknown"}`, + `{"adUnitId": "27604970", "publisherId": "abc123", "integrationType": "ronId"}`, } diff --git a/adapters/seedtag/seedtag.go b/adapters/seedtag/seedtag.go index 7836f2aaff..e48886b875 100644 --- a/adapters/seedtag/seedtag.go +++ b/adapters/seedtag/seedtag.go @@ -6,10 +6,10 @@ import ( "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/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { @@ -51,6 +51,8 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E } requestCopy := *request + // Set the CUR of bid to USD after converting all floors + requestCopy.Cur = []string{"USD"} requestCopy.Imp = imps requestJSON, err := jsonutil.Marshal(requestCopy) if err != nil { diff --git a/adapters/seedtag/seedtag_test.go b/adapters/seedtag/seedtag_test.go index bdfbc7725e..4629793ffd 100644 --- a/adapters/seedtag/seedtag_test.go +++ b/adapters/seedtag/seedtag_test.go @@ -3,9 +3,9 @@ package seedtag 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/seedtag/seedtagtest/exemplary/banner.json b/adapters/seedtag/seedtagtest/exemplary/banner.json index 8e390c4134..3493131ab7 100644 --- a/adapters/seedtag/seedtagtest/exemplary/banner.json +++ b/adapters/seedtag/seedtagtest/exemplary/banner.json @@ -39,6 +39,7 @@ "Accept": ["application/json"] }, "body": { + "cur": ["USD"], "id": "test-request-id", "imp": [ { diff --git a/adapters/seedtag/seedtagtest/exemplary/bidfloor_converted.json b/adapters/seedtag/seedtagtest/exemplary/bidfloor_converted.json index de0991c1e6..c109875df4 100644 --- a/adapters/seedtag/seedtagtest/exemplary/bidfloor_converted.json +++ b/adapters/seedtag/seedtagtest/exemplary/bidfloor_converted.json @@ -53,6 +53,7 @@ "Accept": ["application/json"] }, "body": { + "cur": ["USD"], "id": "test-request-id", "imp": [ { diff --git a/adapters/seedtag/seedtagtest/exemplary/ron_id.json b/adapters/seedtag/seedtagtest/exemplary/ron_id.json new file mode 100644 index 0000000000..f09c9b9b3e --- /dev/null +++ b/adapters/seedtag/seedtagtest/exemplary/ron_id.json @@ -0,0 +1,128 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "publisherId": "abc123", + "integrationType": "ronId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://url.seedtag.com", + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"] + }, + "body": { + "cur": ["USD"], + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "publisherId": "abc123", + "integrationType": "ronId" + } + } + } + ], + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "123", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "12341234", + "adm": "some-test-ad", + "adomain": [ + "domain.com" + ], + "iurl": "http://abc.com/cr?id=12341234", + "cid": "123", + "crid": "12341234", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "12341234", + "adomain": [ + "domain.com" + ], + "iurl": "http://abc.com/cr?id=12341234", + "cid": "123", + "crid": "12341234", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/seedtag/seedtagtest/exemplary/video.json b/adapters/seedtag/seedtagtest/exemplary/video.json index 6bfbc52ad2..d8ac06fbbe 100644 --- a/adapters/seedtag/seedtagtest/exemplary/video.json +++ b/adapters/seedtag/seedtagtest/exemplary/video.json @@ -41,6 +41,7 @@ "Accept": ["application/json"] }, "body": { + "cur": ["USD"], "id": "test-request-id", "imp": [ { diff --git a/adapters/seedtag/seedtagtest/supplemental/invalid_mtype.json b/adapters/seedtag/seedtagtest/supplemental/invalid_mtype.json index 636cb0ce97..ed830f90b4 100644 --- a/adapters/seedtag/seedtagtest/supplemental/invalid_mtype.json +++ b/adapters/seedtag/seedtagtest/supplemental/invalid_mtype.json @@ -37,6 +37,7 @@ "expectedRequest": { "uri": "http://url.seedtag.com", "body": { + "cur": ["USD"], "id": "test-request-id", "imp": [ { diff --git a/adapters/seedtag/seedtagtest/supplemental/response_unmarshal_error.json b/adapters/seedtag/seedtagtest/supplemental/response_unmarshal_error.json index de60e366d4..f61a38f3c0 100644 --- a/adapters/seedtag/seedtagtest/supplemental/response_unmarshal_error.json +++ b/adapters/seedtag/seedtagtest/supplemental/response_unmarshal_error.json @@ -37,6 +37,7 @@ "expectedRequest": { "uri": "http://url.seedtag.com", "body": { + "cur": ["USD"], "id": "test-request-id", "imp": [ { diff --git a/adapters/seedtag/seedtagtest/supplemental/status_bad_request.json b/adapters/seedtag/seedtagtest/supplemental/status_bad_request.json index 8cd058864e..27185ea89a 100644 --- a/adapters/seedtag/seedtagtest/supplemental/status_bad_request.json +++ b/adapters/seedtag/seedtagtest/supplemental/status_bad_request.json @@ -29,6 +29,7 @@ "expectedRequest": { "uri": "http://url.seedtag.com", "body": { + "cur": ["USD"], "id": "test-request-id", "imp": [ { diff --git a/adapters/seedtag/seedtagtest/supplemental/status_no_content.json b/adapters/seedtag/seedtagtest/supplemental/status_no_content.json index aa415e17ed..b9aeff0796 100644 --- a/adapters/seedtag/seedtagtest/supplemental/status_no_content.json +++ b/adapters/seedtag/seedtagtest/supplemental/status_no_content.json @@ -29,6 +29,7 @@ "expectedRequest": { "uri": "http://url.seedtag.com", "body": { + "cur": ["USD"], "id": "test-request-id", "imp": [ { diff --git a/adapters/seedtag/seedtagtest/supplemental/status_not_ok.json b/adapters/seedtag/seedtagtest/supplemental/status_not_ok.json index a5d8f80b41..20b2eb2600 100644 --- a/adapters/seedtag/seedtagtest/supplemental/status_not_ok.json +++ b/adapters/seedtag/seedtagtest/supplemental/status_not_ok.json @@ -29,6 +29,7 @@ "expectedRequest": { "uri": "http://url.seedtag.com", "body": { + "cur": ["USD"], "id": "test-request-id", "imp": [ { diff --git a/adapters/sharethrough/params_test.go b/adapters/sharethrough/params_test.go index a7011ab376..03c60cec38 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/sharethrough/sharethrough.go b/adapters/sharethrough/sharethrough.go index cf5c65a736..7663122788 100644 --- a/adapters/sharethrough/sharethrough.go +++ b/adapters/sharethrough/sharethrough.go @@ -7,12 +7,12 @@ import ( "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" - "github.com/prebid/prebid-server/v3/version" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/version" ) var adapterVersion = "10.0" diff --git a/adapters/sharethrough/sharethrough_test.go b/adapters/sharethrough/sharethrough_test.go index 6ca7d9c7ef..fd2c5d12ed 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/showheroes/params_test.go b/adapters/showheroes/params_test.go index a22693f81a..857a9db650 100644 --- a/adapters/showheroes/params_test.go +++ b/adapters/showheroes/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/showheroes/showheroes.go b/adapters/showheroes/showheroes.go index f04adc100d..c2c27b64b1 100644 --- a/adapters/showheroes/showheroes.go +++ b/adapters/showheroes/showheroes.go @@ -6,12 +6,12 @@ import ( "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" - "github.com/prebid/prebid-server/v3/version" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/version" ) type adapter struct { diff --git a/adapters/showheroes/showheroes_test.go b/adapters/showheroes/showheroes_test.go index 64f8e62f2f..ce82c89255 100644 --- a/adapters/showheroes/showheroes_test.go +++ b/adapters/showheroes/showheroes_test.go @@ -3,9 +3,9 @@ package showheroes 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/silvermob/params_test.go b/adapters/silvermob/params_test.go index 9dc9a34eb6..c59190d561 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 b51207f13c..062264e4c6 100644 --- a/adapters/silvermob/silvermob.go +++ b/adapters/silvermob/silvermob.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type SilverMobAdapter struct { diff --git a/adapters/silvermob/silvermob_test.go b/adapters/silvermob/silvermob_test.go index 991a758b4e..217dfb7db2 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/silverpush/params_test.go b/adapters/silverpush/params_test.go index d98f413a71..721fd69f56 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 049b0d5a93..f5b9ac0588 100644 --- a/adapters/silverpush/silverpush.go +++ b/adapters/silverpush/silverpush.go @@ -6,12 +6,12 @@ import ( "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" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) const ( diff --git a/adapters/silverpush/silverpush_test.go b/adapters/silverpush/silverpush_test.go index f953584f0b..cfb7d296f4 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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smaato/native.go b/adapters/smaato/native.go index 2cbcae471c..ce73d3d73b 100644 --- a/adapters/smaato/native.go +++ b/adapters/smaato/native.go @@ -4,8 +4,8 @@ import ( "encoding/json" "fmt" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type nativeAd struct { diff --git a/adapters/smaato/params_test.go b/adapters/smaato/params_test.go index 7acb42c696..99aea5af5a 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file intends to test static/bidder-params/smaato.json diff --git a/adapters/smaato/smaato.go b/adapters/smaato/smaato.go index 34800102b8..c782e7fa18 100644 --- a/adapters/smaato/smaato.go +++ b/adapters/smaato/smaato.go @@ -9,13 +9,13 @@ import ( "github.com/buger/jsonparser" "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/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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/timeutil" ) const clientVersion = "prebid_server_1.2" diff --git a/adapters/smaato/smaato_test.go b/adapters/smaato/smaato_test.go index 311724ecd8..bc1d3497af 100644 --- a/adapters/smaato/smaato_test.go +++ b/adapters/smaato/smaato_test.go @@ -10,11 +10,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" "github.com/stretchr/testify/assert" - "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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/smartadserver/params_test.go b/adapters/smartadserver/params_test.go index fb71edb414..46266e4be8 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 1dc801a90d..464084fd61 100644 --- a/adapters/smartadserver/smartadserver.go +++ b/adapters/smartadserver/smartadserver.go @@ -9,11 +9,11 @@ import ( "strconv" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type SmartAdserverAdapter struct { diff --git a/adapters/smartadserver/smartadserver_test.go b/adapters/smartadserver/smartadserver_test.go index 51b1fb0914..bb90a4877b 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/smarthub/params_test.go b/adapters/smarthub/params_test.go index 18616abd0f..5a2371f8e8 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/smarthub/smarthub.go b/adapters/smarthub/smarthub.go index 7048bb0cc0..733813bd82 100644 --- a/adapters/smarthub/smarthub.go +++ b/adapters/smarthub/smarthub.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/adapters/smarthub/smarthub_test.go b/adapters/smarthub/smarthub_test.go index bee9c04aa8..bb88ab1312 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smartrtb/smartrtb.go b/adapters/smartrtb/smartrtb.go index 68fd9bfccb..2e498c57d7 100644 --- a/adapters/smartrtb/smartrtb.go +++ b/adapters/smartrtb/smartrtb.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // Base adapter structure. diff --git a/adapters/smartrtb/smartrtb_test.go b/adapters/smartrtb/smartrtb_test.go index 060323a7ac..5e1fd42a29 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smartx/params_test.go b/adapters/smartx/params_test.go index 837c63568a..904586b782 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/smartx/smartx.go b/adapters/smartx/smartx.go index 154f511f03..8a15bb6268 100644 --- a/adapters/smartx/smartx.go +++ b/adapters/smartx/smartx.go @@ -7,10 +7,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/smartx/smartx_test.go b/adapters/smartx/smartx_test.go index 6d25752865..e04f4aa7aa 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testsDir = "smartxtest" diff --git a/adapters/smartyads/params_test.go b/adapters/smartyads/params_test.go index ed49894629..f33095cc51 100644 --- a/adapters/smartyads/params_test.go +++ b/adapters/smartyads/params_test.go @@ -4,11 +4,16 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ - `{ "host": "ep1", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "host", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "host.example.com", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "host.example.com:8080", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "host-example.test", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "Host.Example.com", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "localhost:3000", "sourceid": "partner", "accountid": "hash" }`, } func TestValidParams(t *testing.T) { @@ -34,8 +39,18 @@ var invalidParams = []string{ `{}`, `{"adCode": "string", "seatCode": 5, "originalPublisherid": "string"}`, `{ "host": "ep1", "sourceid": "partner" }`, - `{ "host": "ep1, "accountid": "hash" }`, - `{ "sourceid": "partner", "sourceid": "partner" }`, + `{ "host": "ep1", "accountid": "hash" }`, + `{ "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "", "sourceid": "", "accountid": "" }`, + `{ "host": "/path", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "//evil.com", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "host/path", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "host?query=1", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "host#fragment", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "user@host", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "https://host.com", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "host:notaport", "sourceid": "partner", "accountid": "hash" }`, + `{ "host": "host:8080:extra", "sourceid": "partner", "accountid": "hash" }`, } func TestInvalidParams(t *testing.T) { diff --git a/adapters/smartyads/smartyads.go b/adapters/smartyads/smartyads.go index 3a07edaf62..5be15f1158 100644 --- a/adapters/smartyads/smartyads.go +++ b/adapters/smartyads/smartyads.go @@ -8,12 +8,13 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/urlutil" ) type SmartyAdsAdapter struct { @@ -125,6 +126,9 @@ func (a *SmartyAdsAdapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.Ext } func (a *SmartyAdsAdapter) buildEndpointURL(params *openrtb_ext.ExtSmartyAds) (string, error) { + if !urlutil.IsSafeHost(params.Host) { + return "", &errortypes.BadInput{Message: "Invalid Host"} + } endpointParams := macros.EndpointTemplateParams{Host: params.Host, SourceId: params.SourceID, AccountID: params.AccountID} return macros.ResolveMacros(a.endpoint, endpointParams) } diff --git a/adapters/smartyads/smartyads_test.go b/adapters/smartyads/smartyads_test.go index 330f3900a0..9b7ada132b 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smartyads/smartyadstest/supplemental/invalid-host.json b/adapters/smartyads/smartyadstest/supplemental/invalid-host.json new file mode 100644 index 0000000000..10f8a8f6e8 --- /dev/null +++ b/adapters/smartyads/smartyadstest/supplemental/invalid-host.json @@ -0,0 +1,31 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "host": "evil.com/path?redirect=http://attacker.com#", + "sourceid": "partner", + "accountid": "testaccount" + } + } + } + ], + "site": { + "page": "test.com" + } + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Invalid Host", + "comparison": "literal" + } + ] +} diff --git a/adapters/smilewanted/params_test.go b/adapters/smilewanted/params_test.go index 78a29dc046..cfca29976f 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 3a8efdf0bb..453c2ecb20 100644 --- a/adapters/smilewanted/smilewanted.go +++ b/adapters/smilewanted/smilewanted.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/smilewanted/smilewanted_test.go b/adapters/smilewanted/smilewanted_test.go index 8e291eb505..43dc10a7cc 100644 --- a/adapters/smilewanted/smilewanted_test.go +++ b/adapters/smilewanted/smilewanted_test.go @@ -7,10 +7,10 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smoot/params_test.go b/adapters/smoot/params_test.go index ef0ec2149b..259e97308d 100644 --- a/adapters/smoot/params_test.go +++ b/adapters/smoot/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/smoot/smoot.go b/adapters/smoot/smoot.go index e23c2de602..9a0df2b4a6 100644 --- a/adapters/smoot/smoot.go +++ b/adapters/smoot/smoot.go @@ -6,10 +6,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/smoot/smoot_test.go b/adapters/smoot/smoot_test.go index 46c6586241..7e4d67fd0e 100644 --- a/adapters/smoot/smoot_test.go +++ b/adapters/smoot/smoot_test.go @@ -3,9 +3,9 @@ package smoot 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/smrtconnect/smrtconnect.go b/adapters/smrtconnect/smrtconnect.go index 4ecde49cea..b462b460f0 100644 --- a/adapters/smrtconnect/smrtconnect.go +++ b/adapters/smrtconnect/smrtconnect.go @@ -6,12 +6,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/smrtconnect/smrtconnect_test.go b/adapters/smrtconnect/smrtconnect_test.go index 2b020c1e3a..f715f81411 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/sonobi/params_test.go b/adapters/sonobi/params_test.go index 7ffff8ffdd..eae150661f 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 cf00595c6b..b4adb57e17 100644 --- a/adapters/sonobi/sonobi.go +++ b/adapters/sonobi/sonobi.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // SonobiAdapter - Sonobi SonobiAdapter definition diff --git a/adapters/sonobi/sonobi_test.go b/adapters/sonobi/sonobi_test.go index aa9f44ed7a..35fc29b8f8 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/sovrn/params_test.go b/adapters/sovrn/params_test.go index 021043c1c6..873ec63a1e 100644 --- a/adapters/sovrn/params_test.go +++ b/adapters/sovrn/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/sovrn/sovrn.go b/adapters/sovrn/sovrn.go index 8276c07045..25bbced73f 100644 --- a/adapters/sovrn/sovrn.go +++ b/adapters/sovrn/sovrn.go @@ -8,11 +8,11 @@ import ( "strconv" "strings" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) diff --git a/adapters/sovrn/sovrn_test.go b/adapters/sovrn/sovrn_test.go index f2d61d166e..12545b3f6f 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/sovrnXsp/params_test.go b/adapters/sovrnXsp/params_test.go index 91d31ec54d..2c7270420f 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/sovrnXsp/sovrnXsp.go b/adapters/sovrnXsp/sovrnXsp.go index 7dc90adfd7..2a04443233 100644 --- a/adapters/sovrnXsp/sovrnXsp.go +++ b/adapters/sovrnXsp/sovrnXsp.go @@ -5,11 +5,11 @@ import ( "fmt" "net/http" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) diff --git a/adapters/sovrnXsp/sovrnXsp_test.go b/adapters/sovrnXsp/sovrnXsp_test.go index 3a82e29a54..6c7e4c546b 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/sparteo/params_test.go b/adapters/sparteo/params_test.go index 209093d1ef..c7b8d162de 100644 --- a/adapters/sparteo/params_test.go +++ b/adapters/sparteo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/sparteo.json diff --git a/adapters/sparteo/sparteo.go b/adapters/sparteo/sparteo.go index 100d5acc71..0a8f0fb286 100644 --- a/adapters/sparteo/sparteo.go +++ b/adapters/sparteo/sparteo.go @@ -3,29 +3,33 @@ package sparteo import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) type adapter struct { - endpoint string - bidderName string + endpoint string } type extBidWrapper struct { Prebid openrtb_ext.ExtBidPrebid `json:"prebid"` } +const unknownValue = "unknown" + func Builder(bidderName openrtb_ext.BidderName, cfg config.Adapter, server config.Server) (adapters.Bidder, error) { - return &adapter{ - endpoint: cfg.Endpoint, - bidderName: string(bidderName), - }, nil + bidder := &adapter{ + endpoint: cfg.Endpoint, + } + return bidder, nil } func parseExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpSparteo, error) { @@ -47,6 +51,7 @@ func parseExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpSparteo, error) { func (a *adapter) MakeRequests(req *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { request := *req + var errs []error request.Imp = make([]openrtb2.Imp, len(req.Imp)) copy(request.Imp, req.Imp) @@ -54,25 +59,53 @@ func (a *adapter) MakeRequests(req *openrtb2.BidRequest, reqInfo *adapters.Extra if req.Site != nil { siteCopy := *req.Site request.Site = &siteCopy + if req.Site.Publisher != nil { + pubCopy := *req.Site.Publisher + request.Site.Publisher = &pubCopy + } } - - if req.Site != nil && req.Site.Publisher != nil { - publisherCopy := *req.Site.Publisher - request.Site.Publisher = &publisherCopy + if req.App != nil { + appCopy := *req.App + request.App = &appCopy + if req.App.Publisher != nil { + pubCopy := *req.App.Publisher + request.App.Publisher = &pubCopy + } } - var errs []error - var siteNetworkId string + var siteDomain, appDomain, bundle string + if request.Site != nil { + if sd := resolveSiteDomain(request.Site); sd != nil { + siteDomain = *sd + if siteDomain == unknownValue { + errs = append(errs, &errortypes.BadInput{ + Message: "Domain not found. Missing the site.domain or the site.page field", + }) + } + } + } else if request.App != nil { + if ad := resolveAppDomain(request.App); ad != nil { + appDomain = *ad + } + if b := resolveBundle(request.App); b != nil { + bundle = *b + if bundle == unknownValue { + errs = append(errs, &errortypes.BadInput{ + Message: "Bundle not found. Missing the app.bundle field.", + }) + } + } + } + var networkID string for i, imp := range request.Imp { extImpSparteo, err := parseExt(&imp) if err != nil { errs = append(errs, err) continue } - - if siteNetworkId == "" && extImpSparteo.NetworkId != "" { - siteNetworkId = extImpSparteo.NetworkId + if networkID == "" && extImpSparteo.NetworkId != "" { + networkID = extImpSparteo.NetworkId } var extMap map[string]interface{} @@ -93,12 +126,10 @@ func (a *adapter) MakeRequests(req *openrtb2.BidRequest, reqInfo *adapters.Extra sparteoMap["params"] = paramsMap } - bidderObj, ok := extMap["bidder"].(map[string]interface{}) - if ok { + if bidderObj, ok := extMap["bidder"].(map[string]interface{}); ok { delete(extMap, "bidder") - - for key, value := range bidderObj { - paramsMap[key] = value + for k, v := range bidderObj { + paramsMap[k] = v } } @@ -107,40 +138,32 @@ func (a *adapter) MakeRequests(req *openrtb2.BidRequest, reqInfo *adapters.Extra errs = append(errs, fmt.Errorf("ignoring imp id=%s, error while marshaling updated ext, err: %s", imp.ID, err)) continue } - request.Imp[i].Ext = updatedExt } - if request.Site != nil && request.Site.Publisher != nil && siteNetworkId != "" { - var pubExt map[string]interface{} - if request.Site.Publisher.Ext != nil { - if err := jsonutil.Unmarshal(request.Site.Publisher.Ext, &pubExt); err != nil { - pubExt = make(map[string]interface{}) - } - } else { - pubExt = make(map[string]interface{}) - } - - var paramsMap map[string]interface{} - if raw, ok := pubExt["params"]; ok { - if paramsMap, ok = raw.(map[string]interface{}); !ok { - paramsMap = make(map[string]interface{}) - } - } else { - paramsMap = make(map[string]interface{}) - } - - paramsMap["networkId"] = siteNetworkId - pubExt["params"] = paramsMap + var pub *openrtb2.Publisher + var pubExt string + + if request.Site != nil { + pub = ensurePublisher(request.Site.Publisher) + request.Site.Publisher = pub + pubExt = "site.publisher.ext" + } else if request.App != nil { + pub = ensurePublisher(request.App.Publisher) + request.App.Publisher = pub + pubExt = "app.publisher.ext" + } else { + request.Site = &openrtb2.Site{} + pub = ensurePublisher(request.Site.Publisher) + request.Site.Publisher = pub + pubExt = "site.publisher.ext" + } - updatedPubExt, err := jsonutil.Marshal(pubExt) - if err != nil { - errs = append(errs, &errortypes.BadInput{ - Message: fmt.Sprintf("Error marshaling site.publisher.ext: %s", err), - }) - } else { - request.Site.Publisher.Ext = jsonutil.RawMessage(updatedPubExt) - } + ext, err := updatePublisherExtension(&pub.Ext, networkID, pubExt) + if err != nil { + errs = append(errs, err) + } else { + pub.Ext = ext } body, err := jsonutil.Marshal(request) @@ -149,9 +172,14 @@ func (a *adapter) MakeRequests(req *openrtb2.BidRequest, reqInfo *adapters.Extra return nil, errs } + uri, err := a.buildEndpointURL(networkID, siteDomain, appDomain, bundle) + if err != nil { + return nil, []error{err} + } + requestData := &adapters.RequestData{ Method: http.MethodPost, - Uri: a.endpoint, + Uri: uri, Body: body, ImpIDs: openrtb_ext.GetImpIDs(request.Imp), Headers: http.Header{ @@ -162,6 +190,148 @@ func (a *adapter) MakeRequests(req *openrtb2.BidRequest, reqInfo *adapters.Extra return []*adapters.RequestData{requestData}, errs } +func normalizeHostname(host string) string { + host = strings.TrimSpace(host) + if host == "" { + return "" + } + + u, err := url.Parse(host) + if err != nil || u.Hostname() == "" { + if i := strings.Index(host, ":"); i >= 0 { + host = host[:i] + } else if i := strings.Index(host, "/"); i >= 0 { + host = host[:i] + } + } else { + host = u.Hostname() + } + + host = strings.ToLower(host) + host = strings.TrimSuffix(host, ".") + host = strings.TrimPrefix(host, "www.") + + if host == "null" { + return "" + } + return host +} + +func resolveSiteDomain(site *openrtb2.Site) *string { + if site != nil { + if d := normalizeHostname(site.Domain); d != "" { + return ptrutil.ToPtr(d) + } + if fromPage := normalizeHostname(site.Page); fromPage != "" { + return ptrutil.ToPtr(fromPage) + } + return ptrutil.ToPtr(unknownValue) + } + return nil +} + +func resolveAppDomain(app *openrtb2.App) *string { + if app != nil { + if d := normalizeHostname(app.Domain); d != "" { + return ptrutil.ToPtr(d) + } + return ptrutil.ToPtr(unknownValue) + } + return nil +} + +func resolveBundle(app *openrtb2.App) *string { + if app == nil { + return nil + } + + raw := app.Bundle + if strings.TrimSpace(raw) == "" { + return ptrutil.ToPtr(unknownValue) + } + + b := strings.TrimSpace(raw) + if strings.EqualFold(b, "null") { + return ptrutil.ToPtr(unknownValue) + } + + return ptrutil.ToPtr(b) +} + +func ensurePublisher(p *openrtb2.Publisher) *openrtb2.Publisher { + if p == nil { + p = &openrtb2.Publisher{} + } + if p.Ext == nil { + p.Ext = jsonutil.RawMessage("{}") + } + + return p +} + +func updatePublisherExtension(targetExt *jsonutil.RawMessage, networkID, fieldPath string) ([]byte, error) { + var pubExt map[string]interface{} + if err := jsonutil.Unmarshal(*targetExt, &pubExt); err != nil { + pubExt = make(map[string]interface{}) + } + + params, ok := pubExt["params"].(map[string]interface{}) + if !ok { + params = make(map[string]interface{}) + pubExt["params"] = params + } + params["networkId"] = networkID + + updated, err := jsonutil.Marshal(pubExt) + if err != nil { + return nil, &errortypes.BadInput{ + Message: fmt.Sprintf("Error marshaling %s: %s", fieldPath, err), + } + } + return updated, nil +} + +func (a *adapter) buildEndpointURL(networkId string, siteDomain string, appDomain string, bundle string) (string, error) { + parsed, err := url.Parse(a.endpoint) + if err != nil { + return "", fmt.Errorf("invalid endpoint URL %q: %w", a.endpoint, err) + } + + hasSite := siteDomain != "" + hasAppOrBundle := appDomain != "" || bundle != "" + + var b strings.Builder + + b.WriteString("network_id=") + b.WriteString(url.QueryEscape(networkId)) + + if hasSite { + v := siteDomain + if v == "" { + v = unknownValue + } + b.WriteString("&site_domain=") + b.WriteString(url.QueryEscape(v)) + } else if hasAppOrBundle { + ad := appDomain + if ad == "" { + ad = unknownValue + } + bd := bundle + if bd == "" { + bd = unknownValue + } + + b.WriteString("&app_domain=") + b.WriteString(url.QueryEscape(ad)) + b.WriteString("&bundle=") + b.WriteString(url.QueryEscape(bd)) + } + + parsed.RawQuery = b.String() + return parsed.String(), nil +} + func (a *adapter) MakeBids(req *openrtb2.BidRequest, reqData *adapters.RequestData, respData *adapters.ResponseData) (*adapters.BidderResponse, []error) { if adapters.IsResponseStatusCodeNoContent(respData) { return nil, nil diff --git a/adapters/sparteo/sparteo_test.go b/adapters/sparteo/sparteo_test.go index 527f98b37e..8157c89815 100644 --- a/adapters/sparteo/sparteo_test.go +++ b/adapters/sparteo/sparteo_test.go @@ -2,30 +2,29 @@ package sparteo import ( "encoding/json" + "errors" "testing" "github.com/prebid/openrtb/v20/openrtb2" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -// TestBuilder verifies that the Builder function correctly creates a bidder instance. -// It checks for errors, ensures the returned bidder is not nil, and confirms that the endpoint -// in the adapter is set according to the configuration. +// TestBuilder verifies that the Builder function correctly creates a bidder instance +// and that the endpoint template renders fields using the new macros. func TestBuilder(t *testing.T) { - cfg := config.Adapter{Endpoint: "https://bid-test.sparteo.com/s2s-auction"} - bidder, err := Builder(openrtb_ext.BidderSparteo, cfg, config.Server{GvlID: 1028}) - - require.NoError(t, err, "Builder returned an error") - assert.NotNil(t, bidder, "Bidder is nil") - - sparteoAdapter, ok := bidder.(*adapter) - require.True(t, ok, "Expected *adapter, got %T", bidder) - - assert.Equal(t, "https://bid-test.sparteo.com/s2s-auction", sparteoAdapter.endpoint, "Endpoint is not correctly set") + cfg := config.Adapter{ + Endpoint: "https://bid-test.sparteo.com/s2s-auction", + } + bidder, err := Builder(openrtb_ext.BidderSparteo, cfg, config.Server{}) + if assert.NoError(t, err) { + assert.NotNil(t, bidder) + } } // TestJsonSamples runs JSON sample tests using the shared adapterstest framework. @@ -73,3 +72,716 @@ func TestGetMediaType_NilExt(t *testing.T) { assert.Error(t, err, "Expected error for nil extension") assert.Equal(t, openrtb_ext.BidType(""), result, "Expected empty result for nil extension") } + +// TestMakeRequests_ResolvesQueryParams verifies that the adapter correctly resolves macros in the endpoint URL for Site traffic. +func TestMakeRequests_ResolvesQueryParams(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{ + Endpoint: endpoint, + }, config.Server{GvlID: 1028}) + require.NoError(t, err, "Builder returned an error") + + in := &openrtb2.BidRequest{ + ID: "req-qp-1", + Site: &openrtb2.Site{ + Domain: "dev.sparteo.com", + }, + Imp: []openrtb2.Imp{ + { + ID: "imp-1", + Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`), + }, + }, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1, "Expected exactly one outgoing request") + assert.Empty(t, errs, "Unexpected adapter errors") + + expectedURI := "https://bid-test.sparteo.com/s2s-auction?network_id=networkID&site_domain=dev.sparteo.com" + assert.Equal(t, expectedURI, reqs[0].Uri) +} + +// TestMakeRequests_AppBundleMacro verifies that the adapter correctly resolves app_domain and bundle for App traffic. +func TestMakeRequests_AppBundleMacro(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + ID: "req-app-bundle-1", + App: &openrtb2.App{ + Domain: "dev.sparteo.com", + Bundle: "com.sparteo.app", + Publisher: &openrtb2.Publisher{ + ID: "sparteo", + }, + }, + Imp: []openrtb2.Imp{{ + ID: "imp-1", + Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`), + }}, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + assert.Empty(t, errs) + + expected := "https://bid-test.sparteo.com/s2s-auction?network_id=networkID&app_domain=dev.sparteo.com&bundle=com.sparteo.app" + assert.Equal(t, expected, reqs[0].Uri, "endpoint should include app_domain and bundle for App traffic") +} + +// TestMakeRequests_AppBundleMissing_AppendsUnknown verifies that when app.bundle is empty or missing we send bundle=unknown (and warn). +func TestMakeRequests_AppBundleMissing_AppendsUnknown(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + ID: "req-app-nobundle-1", + App: &openrtb2.App{ + Domain: "dev.sparteo.com", + Publisher: &openrtb2.Publisher{ID: "sparteo"}, + }, + Imp: []openrtb2.Imp{{ + ID: "imp-1", + Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`), + }}, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Len(t, errs, 1) + + expected := "https://bid-test.sparteo.com/s2s-auction?network_id=networkID&app_domain=dev.sparteo.com&bundle=unknown" + assert.Equal(t, expected, reqs[0].Uri, "endpoint should contain bundle=unknown when app.bundle is empty") +} + +// TestMakeRequests_SiteDomain verifies that the adapter uses site.Domain and does not include app fields for Site traffic. +func TestMakeRequests_SiteDomain(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{ + Endpoint: endpoint, + }, config.Server{GvlID: 1028}) + require.NoError(t, err, "Builder returned an error") + + in := &openrtb2.BidRequest{ + ID: "req-fallback-1", + Site: &openrtb2.Site{ + Domain: "dev.sparteo.com", + }, + Imp: []openrtb2.Imp{ + { + ID: "imp-1", + Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`), + }, + }, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1, "Expected exactly one outgoing request") + assert.Empty(t, errs, "Unexpected adapter errors") + + expectedURI := "https://bid-test.sparteo.com/s2s-auction?network_id=networkID&site_domain=dev.sparteo.com" + assert.Equal(t, expectedURI, reqs[0].Uri) +} + +// TestMakeRequests_DomainPrecedence_SiteDomainWins verifies that Site wins over App when both exist. +func TestMakeRequests_DomainPrecedence_SiteDomainWins(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + ID: "req-domain-1", + Site: &openrtb2.Site{ + Domain: "site.sparteo.com", + Publisher: &openrtb2.Publisher{ + Domain: "site-pub.sparteo.com", + }, + }, + App: &openrtb2.App{ + Domain: "app.sparteo.com", + Publisher: &openrtb2.Publisher{ + Domain: "app-pub.should-not-be-used", + }, + }, + Imp: []openrtb2.Imp{ + {ID: "imp-1", Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`)}, + }, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + + assert.Equal(t, + "https://bid-test.sparteo.com/s2s-auction?network_id=networkID&site_domain=site.sparteo.com", + reqs[0].Uri, + ) +} + +// TestMakeRequests_SitePresentWithEmptyDomain_UsesUnknownNotApp verifies that when Site exists but has no domain/page, we send site_domain=unknown and do NOT use App. +func TestMakeRequests_SitePresentWithEmptyDomain_UsesUnknownNotApp(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + ID: "req-domain-2", + Site: &openrtb2.Site{ + Domain: "", + Publisher: &openrtb2.Publisher{ + Domain: "dev.sparteo.com", + }, + }, + App: &openrtb2.App{ + Domain: "app.sparteo.com", + }, + Imp: []openrtb2.Imp{ + {ID: "imp-1", Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`)}, + }, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Len(t, errs, 1) + + assert.Equal(t, + "https://bid-test.sparteo.com/s2s-auction?network_id=networkID&site_domain=unknown", + reqs[0].Uri, + ) +} + +// TestMakeRequests_DomainPrecedence_AppDomainWhenNoSite verifies that if there is no Site, we use app.domain (and include bundle if present). +func TestMakeRequests_DomainPrecedence_AppDomainWhenNoSite(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + ID: "req-domain-3", + Site: nil, + App: &openrtb2.App{ + Domain: "app.sparteo.com", + Bundle: "com.sparteo.app", + Publisher: &openrtb2.Publisher{ + Domain: "app-pub.should-not-be-used", + }, + }, + Imp: []openrtb2.Imp{ + {ID: "imp-1", Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`)}, + }, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + + assert.Equal(t, + "https://bid-test.sparteo.com/s2s-auction?network_id=networkID&app_domain=app.sparteo.com&bundle=com.sparteo.app", + reqs[0].Uri, + ) +} + +// TestMakeRequests_SitePageWhenNoSiteDomainNoApp verifies that if there is Site without domain but page is present, we use site.page. +func TestMakeRequests_SitePageWhenNoSiteDomainNoApp(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + ID: "req-domain-page", + Site: &openrtb2.Site{ + Domain: "", + Page: "https://www.dev.sparteo.com:3000/some/path?x=1", + }, + App: nil, + Imp: []openrtb2.Imp{ + {ID: "imp-1", Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`)}, + }, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + + assert.Equal(t, + "https://bid-test.sparteo.com/s2s-auction?network_id=networkID&site_domain=dev.sparteo.com", + reqs[0].Uri, + ) +} + +// TestNormalizeHostname_PortAndPathAndURL verifies normalizeHostname behavior. +func TestNormalizeHostname_PortAndPathAndURL(t *testing.T) { + base := "dev.sparteo.com" + + tests := []struct { + name string + in string + out string + }{ + // Bare host + port + {"host_with_port", "www." + base + ":8080", base}, + {"host_upper_with_tls_port", "DEV.SPARTEO.COM:443", base}, + {"host_trailing_dot_with_port", base + ".:8443", base}, + + // Bare host + path + {"host_with_path", base + "/some/path?x=1", base}, + {"www_host_with_path", "www." + base + "/p", base}, + + // Bare host + port + path + {"host_with_port_and_path", base + ":8080/p?q=1", base}, + {"www_host_with_port_and_path", "www." + base + ":3000/some/path", base}, + + // Absolute URLs + {"https_url", "https://www." + base + "/x", base}, + {"http_url_with_port", "http://WWW." + base + ":8080/abc", base}, + + // Scheme-relative URL + {"scheme_relative", "//www." + base + "/x", base}, + + // Odd spacing around URLs/hosts + {"spaced_https_url", " https://www." + base + ":3000/x ", base}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got := normalizeHostname(tc.in) + assert.Equal(t, tc.out, got) + }) + } +} + +// --- Helper for reading publisher.ext.params.networkId in output JSON --- +func readNetworkIDFromPublisherExt(t *testing.T, ext json.RawMessage) (string, bool) { + if len(ext) == 0 { + return "", false + } + var m map[string]interface{} + require.NoError(t, json.Unmarshal(ext, &m)) + params, _ := m["params"].(map[string]interface{}) + if params == nil { + return "", false + } + val, _ := params["networkId"].(string) + if val == "" { + return "", false + } + return val, true +} + +// When site exists but site.publisher is nil, the adapter must create publisher and upsert networkId into site.publisher.ext +func TestMakeRequests_UpdatePublisherExtension_CreatesSitePublisherIfMissing(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + ID: "req-upsert-site", + Site: &openrtb2.Site{ + Domain: "site.sparteo.com", + Publisher: nil, + }, + Imp: []openrtb2.Imp{ + {ID: "imp-1", Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`)}, + }, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + + var out openrtb2.BidRequest + require.NoError(t, json.Unmarshal(reqs[0].Body, &out)) + + require.NotNil(t, out.Site) + require.NotNil(t, out.Site.Publisher, "publisher should be created when missing") + val, ok := readNetworkIDFromPublisherExt(t, out.Site.Publisher.Ext) + require.True(t, ok, "site.publisher.ext.params.networkId should exist") + assert.Equal(t, "networkID", val) +} + +// When no site is present, create app.publisher if missing and upsert networkId into app.publisher.ext +func TestMakeRequests_UpdatePublisherExtension_CreatesAppPublisherIfMissingWhenNoSite(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + ID: "req-upsert-app", + Site: nil, + App: &openrtb2.App{ + Domain: "app.sparteo.com", + Bundle: "com.sparteo.app", + Publisher: nil, + }, + Imp: []openrtb2.Imp{ + {ID: "imp-1", Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`)}, + }, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + + var out openrtb2.BidRequest + require.NoError(t, json.Unmarshal(reqs[0].Body, &out)) + + require.Nil(t, out.Site) + require.NotNil(t, out.App) + require.NotNil(t, out.App.Publisher, "app.publisher should be created when missing") + val, ok := readNetworkIDFromPublisherExt(t, out.App.Publisher.Ext) + require.True(t, ok, "app.publisher.ext.params.networkId should exist") + assert.Equal(t, "networkID", val) +} + +// TestMakeRequests_UpdatePublisherExtension_PrefersSiteOverApp verifies that we prefer Site when both Site and App exist; only Site should receive the networkId +func TestMakeRequests_UpdatePublisherExtension_PrefersSiteOverApp(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + ID: "req-upsert-prefer-site", + Site: &openrtb2.Site{ + Domain: "site.sparteo.com", + Publisher: &openrtb2.Publisher{}, + }, + App: &openrtb2.App{ + Domain: "app.sparteo.com", + Publisher: &openrtb2.Publisher{}, + }, + Imp: []openrtb2.Imp{ + {ID: "imp-1", Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`)}, + }, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + + var out openrtb2.BidRequest + require.NoError(t, json.Unmarshal(reqs[0].Body, &out)) + + require.NotNil(t, out.Site) + require.NotNil(t, out.Site.Publisher) + siteVal, siteOk := readNetworkIDFromPublisherExt(t, out.Site.Publisher.Ext) + require.True(t, siteOk) + assert.Equal(t, "networkID", siteVal) + + if out.App != nil && out.App.Publisher != nil { + _, appOk := readNetworkIDFromPublisherExt(t, out.App.Publisher.Ext) + assert.False(t, appOk, "app.publisher.ext should not contain networkId when site exists") + } +} + +// TestMakeRequests_NoSiteNoApp_NoDomainParam_NoWarning verifies that with neither Site nor App we don't send domain params and produce no warnings. +func TestMakeRequests_NoSiteNoApp_NoDomainParam_NoWarning(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + ID: "req-domain-missing", + Imp: []openrtb2.Imp{ + {ID: "imp-1", Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`)}, + }, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + + require.Len(t, reqs, 1) + require.Len(t, errs, 0) + + assert.Equal(t, + "https://bid-test.sparteo.com/s2s-auction?network_id=networkID", + reqs[0].Uri, + ) +} + +// TestMakeRequests_SitePageLiteralNull_TreatedAsMissingDomain verifies that a literal "null" in site.page is treated as an unknown site domain. +func TestMakeRequests_SitePageLiteralNull_TreatedAsMissingDomain(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s-auction" + + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + ID: "req-page-null", + Site: &openrtb2.Site{ + Domain: "", + Page: "null", + }, + Imp: []openrtb2.Imp{ + {ID: "imp-1", Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`)}, + }, + } + + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + + require.Len(t, reqs, 1) + require.Len(t, errs, 1) + assert.Equal(t, + "https://bid-test.sparteo.com/s2s-auction?network_id=networkID&site_domain=unknown", + reqs[0].Uri, + ) + + var badInput *errortypes.BadInput + require.True(t, errors.As(errs[0], &badInput)) + assert.Contains(t, badInput.Error(), "Domain not found") +} + +// TestMakeRequests_AppBundle_NormalizationVariants ensures blank/whitespace/"null" bundles normalize to "unknown" with a single warning. +func TestMakeRequests_AppBundle_NormalizationVariants(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s" + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + cases := []struct { + name string + bundle string + }{ + {"empty", ""}, + {"spaces", " "}, + {"lower_null", "null"}, + {"weird_case", "NuLl"}, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + in := &openrtb2.BidRequest{ + App: &openrtb2.App{Domain: "dev.sparteo.com", Bundle: tc.bundle, Publisher: &openrtb2.Publisher{}}, + Imp: []openrtb2.Imp{{ID: "i1", Ext: json.RawMessage(`{"bidder":{"networkId":"n"}}`)}}, + } + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Len(t, errs, 1) + assert.Contains(t, reqs[0].Uri, "app_domain=dev.sparteo.com") + assert.Contains(t, reqs[0].Uri, "bundle=unknown") + var badInput *errortypes.BadInput + require.True(t, errors.As(errs[0], &badInput)) + assert.Contains(t, badInput.Error(), "Bundle not found") + }) + } +} + +// TestMakeRequests_SitePresent_IgnoresAppFields ensures when Site is present, only site_domain is sent and app fields are ignored. +func TestMakeRequests_SitePresent_IgnoresAppFields(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s" + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + Site: &openrtb2.Site{Domain: "site.sparteo.com"}, + App: &openrtb2.App{Domain: "app.sparteo.com", Bundle: "com.app"}, + Imp: []openrtb2.Imp{{ID: "i1", Ext: json.RawMessage(`{"bidder":{"networkId":"N"}}`)}}, + } + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + assert.Equal(t, "https://bid-test.sparteo.com/s2s?network_id=N&site_domain=site.sparteo.com", reqs[0].Uri) +} + +// TestMakeRequests_SiteWithPageFallback_IgnoresApp ensures Site.Page is used when Site.Domain is empty and App is ignored when Site exists. +func TestMakeRequests_SiteWithPageFallback_IgnoresApp(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s" + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + Site: &openrtb2.Site{Domain: "", Page: "https://www.example.com:8080/p"}, + App: &openrtb2.App{Domain: "app.sparteo.com", Bundle: "com.app"}, + Imp: []openrtb2.Imp{{ID: "i1", Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`)}}, + } + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + assert.Equal(t, "https://bid-test.sparteo.com/s2s?network_id=networkID&site_domain=example.com", reqs[0].Uri) +} + +// TestMakeRequests_AppMissingBundle_WarnsAndUnknown ensures App with missing bundle yields bundle=unknown and one bundle warning. +func TestMakeRequests_AppMissingBundle_WarnsAndUnknown(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s" + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + App: &openrtb2.App{Domain: "dev.sparteo.com", Bundle: "", Publisher: &openrtb2.Publisher{}}, + Imp: []openrtb2.Imp{{ID: "i1", Ext: json.RawMessage(`{"bidder":{"networkId":"networkID"}}`)}}, + } + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Len(t, errs, 1) + assert.Equal(t, "https://bid-test.sparteo.com/s2s?network_id=networkID&app_domain=dev.sparteo.com&bundle=unknown", reqs[0].Uri) + var badInput *errortypes.BadInput + require.True(t, errors.As(errs[0], &badInput)) + assert.Contains(t, badInput.Error(), "Bundle not found") +} + +// TestMakeRequests_ExtRewrite_MovesBidderIntoSparteoParams verifies bidder object is moved under sparteo.params and bidder is removed. +func TestMakeRequests_ExtRewrite_MovesBidderIntoSparteoParams(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s" + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + Site: &openrtb2.Site{Domain: "dev.sparteo.com"}, + Imp: []openrtb2.Imp{{ID: "i1", Ext: json.RawMessage(`{"bidder":{"a":1}}`)}}, + } + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + + var out openrtb2.BidRequest + require.NoError(t, json.Unmarshal(reqs[0].Body, &out)) + var ext map[string]any + require.NoError(t, json.Unmarshal(out.Imp[0].Ext, &ext)) + _, hasBidder := ext["bidder"] + assert.False(t, hasBidder) + sparteoNode, ok := ext["sparteo"].(map[string]any) + require.True(t, ok) + params, ok := sparteoNode["params"].(map[string]any) + require.True(t, ok) + assert.Equal(t, float64(1), params["a"]) +} + +// TestMakeRequests_ExtRewrite_PreservesExistingSparteoParams verifies existing sparteo.params keys are preserved when merging bidder fields. +func TestMakeRequests_ExtRewrite_PreservesExistingSparteoParams(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s" + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + Site: &openrtb2.Site{Domain: "dev.sparteo.com"}, + Imp: []openrtb2.Imp{{ + ID: "i1", + Ext: json.RawMessage(`{"sparteo":{"params":{"keep":true}},"bidder":{"add":42}}`), + }}, + } + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + + var out openrtb2.BidRequest + require.NoError(t, json.Unmarshal(reqs[0].Body, &out)) + var ext map[string]any + require.NoError(t, json.Unmarshal(out.Imp[0].Ext, &ext)) + sparteoNode, ok := ext["sparteo"].(map[string]any) + require.True(t, ok) + params, ok := sparteoNode["params"].(map[string]any) + require.True(t, ok) + assert.Equal(t, true, params["keep"]) + assert.Equal(t, float64(42), params["add"]) +} + +// TestMakeRequests_NetworkId_FirstNonEmptyWins verifies the first non-empty networkId across imps is used. +func TestMakeRequests_NetworkId_FirstNonEmptyWins(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s" + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + Site: &openrtb2.Site{Domain: "dev.sparteo.com"}, + Imp: []openrtb2.Imp{ + {ID: "i1", Ext: json.RawMessage(`{"bidder":{"networkId":""}}`)}, + {ID: "i2", Ext: json.RawMessage(`{"bidder":{"networkId":"N2"}}`)}, + {ID: "i3", Ext: json.RawMessage(`{"bidder":{"networkId":"N3"}}`)}, + }, + } + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + assert.Equal(t, "https://bid-test.sparteo.com/s2s?network_id=N2&site_domain=dev.sparteo.com", reqs[0].Uri) +} + +// TestMakeRequests_AllImpsBadExt_AggregatesErrors verifies a request is still built when all imps have bad ext and errors are aggregated. +func TestMakeRequests_AllImpsBadExt_AggregatesErrors(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s" + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + in := &openrtb2.BidRequest{ + Site: &openrtb2.Site{Domain: "dev.sparteo.com"}, + Imp: []openrtb2.Imp{ + {ID: "i1", Ext: json.RawMessage(`not-json`)}, + {ID: "i2", Ext: json.RawMessage(`{"bidder":}`)}, + }, + } + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Len(t, errs, 2) + assert.Equal(t, "https://bid-test.sparteo.com/s2s?network_id=&site_domain=dev.sparteo.com", reqs[0].Uri) +} + +// TestMakeRequests_UpdatePublisherExtension_PreservesOtherKeys verifies publisher.ext keeps existing keys while adding params.networkId. +func TestMakeRequests_UpdatePublisherExtension_PreservesOtherKeys(t *testing.T) { + endpoint := "https://bid-test.sparteo.com/s2s" + bidder, err := Builder(openrtb_ext.BidderSparteo, config.Adapter{Endpoint: endpoint}, config.Server{GvlID: 1028}) + require.NoError(t, err) + + startExt := json.RawMessage(`{"params":{"foo":"bar"},"other":123}`) + in := &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Domain: "dev.sparteo.com", + Publisher: &openrtb2.Publisher{Ext: startExt}, + }, + Imp: []openrtb2.Imp{{ID: "i1", Ext: json.RawMessage(`{"bidder":{"networkId":"N"}}`)}}, + } + reqs, errs := bidder.MakeRequests(in, &adapters.ExtraRequestInfo{}) + require.Len(t, reqs, 1) + require.Empty(t, errs) + + var out openrtb2.BidRequest + require.NoError(t, json.Unmarshal(reqs[0].Body, &out)) + var m map[string]any + require.NoError(t, json.Unmarshal(out.Site.Publisher.Ext, &m)) + params, _ := m["params"].(map[string]any) + require.NotNil(t, params) + assert.Equal(t, "bar", params["foo"]) + assert.Equal(t, float64(123), m["other"]) + assert.Equal(t, "N", params["networkId"]) +} + +// TestMakeBids_SkipsAudioBids verifies bids with prebid.type=audio are skipped with no returned errors. +func TestMakeBids_SkipsAudioBids(t *testing.T) { + a := &adapter{} + body := []byte(`{"cur":"USD","seatbid":[{"bid":[{"impid":"1","price":1,"crid":"c","ext":{"prebid":{"type":"audio"}}}]}]}`) + br, errs := a.MakeBids(&openrtb2.BidRequest{}, &adapters.RequestData{}, &adapters.ResponseData{StatusCode: 200, Body: body}) + require.NoError(t, nil) + require.Nil(t, errs) + require.NotNil(t, br) + assert.Equal(t, 0, len(br.Bids)) +} + +// TestMakeBids_SetsMTypeAndCurrency verifies mtype is set correctly for banner/video/native and currency is propagated. +func TestMakeBids_SetsMTypeAndCurrency(t *testing.T) { + a := &adapter{} + body := []byte(`{ + "cur":"EUR", + "seatbid":[{"bid":[ + {"impid":"b1","price":1,"crid":"c1","ext":{"prebid":{"type":"banner"}}}, + {"impid":"v1","price":2,"crid":"c2","ext":{"prebid":{"type":"video"}}}, + {"impid":"n1","price":3,"crid":"c3","ext":{"prebid":{"type":"native"}}} + ]}] + }`) + br, errs := a.MakeBids(&openrtb2.BidRequest{}, &adapters.RequestData{}, &adapters.ResponseData{StatusCode: 200, Body: body}) + require.Nil(t, errs) + require.NotNil(t, br) + require.Equal(t, "EUR", br.Currency) + require.Equal(t, 3, len(br.Bids)) + assert.Equal(t, openrtb2.MarkupBanner, br.Bids[0].Bid.MType) + assert.Equal(t, openrtb2.MarkupVideo, br.Bids[1].Bid.MType) + assert.Equal(t, openrtb2.MarkupNative, br.Bids[2].Bid.MType) +} diff --git a/adapters/sparteo/sparteotest/exemplary/banner-app.json b/adapters/sparteo/sparteotest/exemplary/banner-app.json new file mode 100644 index 0000000000..1e88391f3e --- /dev/null +++ b/adapters/sparteo/sparteotest/exemplary/banner-app.json @@ -0,0 +1,242 @@ +{ + "mockBidRequest": { + "id": "request-id", + "imp": [ + { + "id": "div-banner-id", + "banner": { + "topframe": 1, + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "networkId": "networkId" + } + } + } + ], + "app": { + "domain": "dev.sparteo.com", + "bundle": "com.sparteo.app", + "publisher": { + "domain": "dev.sparteo.com", + "id": "sparteo" + } + }, + "device": { + "w": 1920, + "h": 1080, + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36", + "language": "fr", + "ext": { + "vpw": 1056, + "vph": 934 + }, + "sua": { + "source": 1, + "platform": { + "brand": "macOS" + }, + "browsers": [ + { + "brand": "Chromium", + "version": [ + "134" + ] + }, + { + "brand": "Not:A-Brand", + "version": [ + "24" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "134" + ] + } + ], + "mobile": 0 + } + }, + "ext": { + "prebid": { + "server": { + "datacenter": "", + "externalurl": "", + "gvlid": 1028 + } + }, + "tmaxmax": 5000 + }, + "tmax": 5000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&app_domain=dev.sparteo.com&bundle=com.sparteo.app", + "body": { + "id": "request-id", + "imp": [ + { + "id": "div-banner-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "topframe": 1 + }, + "ext": { + "sparteo": { + "params": { + "networkId": "networkId" + } + } + } + } + ], + "app": { + "domain": "dev.sparteo.com", + "bundle": "com.sparteo.app", + "publisher": { + "domain": "dev.sparteo.com", + "id": "sparteo", + "ext": { + "params": { + "networkId": "networkId" + } + } + } + }, + "device": { + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36", + "sua": { + "browsers": [ + { + "brand": "Chromium", + "version": [ + "134" + ] + }, + { + "brand": "Not:A-Brand", + "version": [ + "24" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "134" + ] + } + ], + "platform": { + "brand": "macOS" + }, + "mobile": 0, + "source": 1 + }, + "h": 1080, + "w": 1920, + "language": "fr", + "ext": { + "vpw": 1056, + "vph": 934 + } + }, + "tmax": 5000, + "ext": { + "prebid": { + "server": { + "externalurl": "", + "gvlid": 1028, + "datacenter": "" + } + }, + "tmaxmax": 5000 + } + }, + "impIDs": [ + "div-banner-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "request-id", + "seatbid": [ + { + "seat": "sparteo", + "bid": [ + { + "id": "137dd2bd-3015-407a-ab50-384aa2c706d7", + "impid": "div-banner-id", + "price": 0.10797, + "nurl": "https://dev.sparteo.com/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", + "adm": "", + "adomain": [ + "testpage-ad" + ], + "crid": "banner_creative_test", + "w": 300, + "h": 250, + "ext": { + "ft": "passthrough", + "prebid": { + "type": "banner" + } + } + } + ] + + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "request-id", + "bids": [ + { + "bid": { + "id": "137dd2bd-3015-407a-ab50-384aa2c706d7", + "impid": "div-banner-id", + "mtype": 1, + "price": 0.10797, + "nurl": "https://dev.sparteo.com/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", + "adm": "", + "adomain": [ + "testpage-ad" + ], + "crid": "banner_creative_test", + "w": 300, + "h": 250, + "ext": { + "ft": "passthrough", + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ], + "cur": "EUR" + } + ] +} \ No newline at end of file diff --git a/adapters/sparteo/sparteotest/exemplary/banner.json b/adapters/sparteo/sparteotest/exemplary/banner.json index 78fa09afc7..f68f57b633 100644 --- a/adapters/sparteo/sparteotest/exemplary/banner.json +++ b/adapters/sparteo/sparteotest/exemplary/banner.json @@ -21,13 +21,13 @@ } ], "site": { - "domain": "dev.sparteo.com:4444", + "domain": "dev.sparteo.com", "publisher": { - "domain": "dev.sparteo.com:4444", + "domain": "dev.sparteo.com", "id": "sparteo" }, - "page": "https://dev.sparteo.com:4444/page/test/", - "ref": "https://dev.sparteo.com:4444/page/test/" + "page": "https://dev.sparteo.com/page/test/", + "ref": "https://dev.sparteo.com/page/test/" }, "device": { "w": 1920, @@ -82,7 +82,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&site_domain=dev.sparteo.com", "body": { "id": "request-id", "imp": [ @@ -107,12 +107,12 @@ } ], "site": { - "domain": "dev.sparteo.com:4444", - "page": "https://dev.sparteo.com:4444/page/test/", - "ref": "https://dev.sparteo.com:4444/page/test/", + "domain": "dev.sparteo.com", + "page": "https://dev.sparteo.com/page/test/", + "ref": "https://dev.sparteo.com/page/test/", "publisher": { "id": "sparteo", - "domain": "dev.sparteo.com:4444", + "domain": "dev.sparteo.com", "ext": { "params": { "networkId": "networkId" @@ -186,7 +186,7 @@ "id": "137dd2bd-3015-407a-ab50-384aa2c706d7", "impid": "div-banner-id", "price": 0.10797, - "nurl": "https://dev.sparteo.com:4444/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", + "nurl": "https://dev.sparteo.com/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", "adm": "", "adomain": [ "testpage-ad" @@ -220,7 +220,7 @@ "impid": "div-banner-id", "mtype": 1, "price": 0.10797, - "nurl": "https://dev.sparteo.com:4444/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", + "nurl": "https://dev.sparteo.com/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", "adm": "", "adomain": [ "testpage-ad" diff --git a/adapters/sparteo/sparteotest/exemplary/native.json b/adapters/sparteo/sparteotest/exemplary/native.json index 2f5b9bcc34..bcbbf8b6ab 100644 --- a/adapters/sparteo/sparteotest/exemplary/native.json +++ b/adapters/sparteo/sparteotest/exemplary/native.json @@ -15,13 +15,13 @@ } ], "site": { - "domain": "dev.sparteo.com:4444", + "domain": "dev.sparteo.com", "publisher": { - "domain": "dev.sparteo.com:4444", + "domain": "dev.sparteo.com", "id": "sparteo" }, - "page": "https://dev.sparteo.com:4444/page/test/", - "ref": "https://dev.sparteo.com:4444/page/test/" + "page": "https://dev.sparteo.com/page/test/", + "ref": "https://dev.sparteo.com/page/test/" }, "device": { "w": 1920, @@ -76,7 +76,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&site_domain=dev.sparteo.com", "body": { "id": "request-id", "imp": [ @@ -95,12 +95,12 @@ } ], "site": { - "domain": "dev.sparteo.com:4444", - "page": "https://dev.sparteo.com:4444/page/test/", - "ref": "https://dev.sparteo.com:4444/page/test/", + "domain": "dev.sparteo.com", + "page": "https://dev.sparteo.com/page/test/", + "ref": "https://dev.sparteo.com/page/test/", "publisher": { "id": "sparteo", - "domain": "dev.sparteo.com:4444", + "domain": "dev.sparteo.com", "ext": { "params": { "networkId": "networkId" @@ -174,7 +174,7 @@ "id": "137dd2bd-3015-407a-ab50-384aa2c706d7", "impid": "div-native-id", "price": 0.10797, - "nurl": "https://dev.sparteo.com:4444/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", + "nurl": "https://dev.sparteo.com/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", "adm": "", "adomain": [ "testpage-ad" @@ -207,7 +207,7 @@ "impid": "div-native-id", "mtype": 4, "price": 0.10797, - "nurl": "https://dev.sparteo.com:4444/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", + "nurl": "https://dev.sparteo.com/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", "adm": "", "adomain": [ "testpage-ad" diff --git a/adapters/sparteo/sparteotest/exemplary/video.json b/adapters/sparteo/sparteotest/exemplary/video.json index f69d646309..12a8c578be 100644 --- a/adapters/sparteo/sparteotest/exemplary/video.json +++ b/adapters/sparteo/sparteotest/exemplary/video.json @@ -43,13 +43,13 @@ } ], "site": { - "domain": "dev.sparteo.com:4444", + "domain": "dev.sparteo.com", "publisher": { - "domain": "dev.sparteo.com:4444", + "domain": "dev.sparteo.com", "id": "sparteo" }, - "page": "https://dev.sparteo.com:4444/page/test/", - "ref": "https://dev.sparteo.com:4444/page/test/" + "page": "https://dev.sparteo.com/page/test/", + "ref": "https://dev.sparteo.com/page/test/" }, "device": { "w": 1920, @@ -104,7 +104,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&site_domain=dev.sparteo.com", "body": { "id": "request-id", "imp": [ @@ -146,12 +146,12 @@ } ], "site": { - "domain": "dev.sparteo.com:4444", - "page": "https://dev.sparteo.com:4444/page/test/", - "ref": "https://dev.sparteo.com:4444/page/test/", + "domain": "dev.sparteo.com", + "page": "https://dev.sparteo.com/page/test/", + "ref": "https://dev.sparteo.com/page/test/", "publisher": { "id": "sparteo", - "domain": "dev.sparteo.com:4444", + "domain": "dev.sparteo.com", "ext": { "params": { "networkId": "networkId" @@ -225,7 +225,7 @@ "id": "137dd2bd-3015-407a-ab50-384aa2c706d7", "impid": "div-video-id", "price": 0.10797, - "nurl": "https://dev.sparteo.com:4444/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", + "nurl": "https://dev.sparteo.com/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", "adm": "", "adomain": [ "testpage-ad" @@ -258,7 +258,7 @@ "impid": "div-video-id", "mtype": 2, "price": 0.10797, - "nurl": "https://dev.sparteo.com:4444/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", + "nurl": "https://dev.sparteo.com/event/sparteo/0a98964d-1cf9-4802-93e9-c59c18f497fa?d=kyGjrlVurDF3FlG8d7juZXMzNlGoZA06b75fJDG9dyF3LTd9LzPxLRHzMzFzMfwfdlifNfF9L7AlLzreYS96MTH9JTP7NRdtNRU4LS8lYTPwZTMlLRPyYTUfJDGjdEPfNfFvdzGzJWA8Y6Qob75fJDG8YSF3FirvJWe9rEHtY7xoZW49JzKuLSFsFmBiFgnfZCV7JmMwYXG9ZW1uY70tNgP9MRPfJDGwrSF3Fle9rEBzGTMBGTGCGTGCZCV7JmMwYXG9ZW1uY70tGTMBMRP9MDUyQmBeZ7UjLiZzZXG7ZXFtrC1td7VyrlVyJWGoZCQobldjLiZzZXG7ZXGUb8MjdmZjdiGoZCQoblrDYW4uZXFfJDGfdmFfNfFfJDGuhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGwhWPfNfGjYlY4ZTi6ZD8iMCMeJTQeLRKtNWL9YS8iLzK8LTPwMzL7ZRYfJDGib6LfNfGtYWMOUyFsFlQfFgnfrW4qbl06bfFsFmVib75fNfG8bltub6ruFfwfrWQ9FgnfZCVzh6QvdDFsFlAfrDF3WyGzd6HtY70tYl1tbW0uZXj9hXojdj0eXzUwFfwfd6MwJWMvbWGvJXB8YlZ8rEVyZV0jbXB9kV18LDFsFlrsb7GebDFsFmBfdy8fhWPtdlA9ZV0OPV1xLRHwFfwfdlV7ZW48ZV0BXzKwLDFsFlGoZD8vdEQaT6B9hW8KXzP8Fj9sFmByZWQzFgo2Flrsb7GebKxjrlVPdlVPdlViFgnxJDGobXBLZXZjbAByZVByZWPfNgKsFlMyZWAadCVyX7jtdDF3LS58MzYsFlGobCxeYlxjX6Bjdj0obXHfNgKsFlVzrCjtYXQjZA0yZXZjbmVjFgnwJgF5NSwfrljvrXMskV0yZXZjbmVadlA9hW1fNgKsFmrobj0yYXQjFgnwJgHyMSwfbWAyZ7juX6ByZWPfNgHuLRH8JDGfhWQadEGoY7UfNgHuLX9sFlGohSF3FlQorf8fYW4uZXFfJDGwbELfNjsfLzHwkRF8LDGrJDGwbXPfNjsfYlAublVyFj9sFlVsdyF3WyFzLRB5LgUwFfwfLzHwkRKwLDFsFgLwLEcxLgUfJDFzLRB5LTUwFj9sFlVtrDF3WyGfYW4uZXFfXSwfYlQzFgobFlAikW08bCjqZSFsFlAwdC4jkEVzFfwfZ6GoZDFsFl0lrC8jZCjeFfwfb74jrCAmFfwfb6BjbmcfJDGyhXMjFfwfdmVfhWMvbfFsFmMtYXG9YWQzZXG7ZXFfJDGzbWjsZXrebmQjZDFsFmVudmVskSGrJDGtYfF3ZlAsd7UsFlZ9dyF3WyGPYXMzVCeyb6VmhKZvdl8erDGrJDGydyF3LD55MSwfYlifNfFxLzriZRGfZD9zLRK8JTPwM7KtYWF8LD9zNRQeYTGgMzH7ZRdfJDGfdDF3LD5xJDGlrDF3FjBed6MUhEGvrWrnQl0ybWA9Fm9=", "adm": "", "adomain": [ "testpage-ad" diff --git a/adapters/sparteo/sparteotest/supplemental/filter-empty-seat-bids.json b/adapters/sparteo/sparteotest/supplemental/filter-empty-seat-bids.json index ded36e22d4..ba66d5820b 100644 --- a/adapters/sparteo/sparteotest/supplemental/filter-empty-seat-bids.json +++ b/adapters/sparteo/sparteotest/supplemental/filter-empty-seat-bids.json @@ -19,12 +19,15 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com" + } }, "httpCalls": [ { "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&site_domain=dev.sparteo.com", "body": { "id": "test-request-id", "imp": [ @@ -47,7 +50,17 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com", + "publisher": { + "ext": { + "params": { + "networkId": "networkId" + } + } + } + } }, "impIDs": [ "div-banner-id" diff --git a/adapters/sparteo/sparteotest/supplemental/filter-invalid-bid-type.json b/adapters/sparteo/sparteotest/supplemental/filter-invalid-bid-type.json index 851fcf1860..ab31a8e67e 100644 --- a/adapters/sparteo/sparteotest/supplemental/filter-invalid-bid-type.json +++ b/adapters/sparteo/sparteotest/supplemental/filter-invalid-bid-type.json @@ -19,12 +19,15 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com" + } }, "httpCalls": [ { "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&site_domain=dev.sparteo.com", "body": { "id": "test-request-id", "imp": [ @@ -47,7 +50,17 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com", + "publisher": { + "ext": { + "params": { + "networkId": "networkId" + } + } + } + } }, "impIDs": ["div-banner-id"] }, diff --git a/adapters/sparteo/sparteotest/supplemental/filter-no-seat-bids.json b/adapters/sparteo/sparteotest/supplemental/filter-no-seat-bids.json index 21e3f35629..0660aee07c 100644 --- a/adapters/sparteo/sparteotest/supplemental/filter-no-seat-bids.json +++ b/adapters/sparteo/sparteotest/supplemental/filter-no-seat-bids.json @@ -19,12 +19,15 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com" + } }, "httpCalls": [ { "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&site_domain=dev.sparteo.com", "body": { "id": "test-request-id", "imp": [ @@ -47,7 +50,17 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com", + "publisher": { + "ext": { + "params": { + "networkId": "networkId" + } + } + } + } }, "impIDs": [ "div-banner-id" diff --git a/adapters/sparteo/sparteotest/supplemental/invalid-bidder-ext.json b/adapters/sparteo/sparteotest/supplemental/invalid-bidder-ext.json deleted file mode 100644 index 61d1d61002..0000000000 --- a/adapters/sparteo/sparteotest/supplemental/invalid-bidder-ext.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "div-banner-id", - "banner": { - "topframe": 1, - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": "not an object" - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "div-banner-id", - "banner": { - "topframe": 1, - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": "not an object" - } - } - ] - }, - "ImpIDs": ["div-banner-id"] - }} - ], - "expectedMakeRequestsErrors": [ - { - "value": "^ignoring imp id=div-banner-id, error while decoding impExt", - "comparison": "regex" - } - ], - "expectedMakeBidsErrors": [ - { - "value": "Unexpected status code: 0. Run with request.debug = 1 for more info", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/sparteo/sparteotest/supplemental/invalid-json-response.json b/adapters/sparteo/sparteotest/supplemental/invalid-json-response.json index 12ad55425b..adb997a503 100644 --- a/adapters/sparteo/sparteotest/supplemental/invalid-json-response.json +++ b/adapters/sparteo/sparteotest/supplemental/invalid-json-response.json @@ -19,12 +19,15 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com" + } }, "httpCalls": [ { "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&site_domain=dev.sparteo.com", "body": { "id": "test-request-id", "imp": [ @@ -47,7 +50,17 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com", + "publisher": { + "ext": { + "params": { + "networkId": "networkId" + } + } + } + } }, "impIDs": [ "div-banner-id" diff --git a/adapters/sparteo/sparteotest/supplemental/invalid-publisher-ext.json b/adapters/sparteo/sparteotest/supplemental/invalid-publisher-ext.json index 5d2bb2148c..73a196772a 100644 --- a/adapters/sparteo/sparteotest/supplemental/invalid-publisher-ext.json +++ b/adapters/sparteo/sparteotest/supplemental/invalid-publisher-ext.json @@ -21,12 +21,12 @@ } ], "site": { - "domain": "dev.sparteo.com:4444", - "page": "https://dev.sparteo.com:4444/page/test/", - "ref": "https://dev.sparteo.com:4444/page/test/", + "domain": "dev.sparteo.com", + "page": "https://dev.sparteo.com/page/test/", + "ref": "https://dev.sparteo.com/page/test/", "publisher": { "id": "sparteo", - "domain": "dev.sparteo.com:4444", + "domain": "dev.sparteo.com", "ext": "not an object" } } @@ -34,7 +34,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&site_domain=dev.sparteo.com", "body": { "id": "test-request-id", "imp": [ @@ -59,10 +59,10 @@ } ], "site": { - "domain": "dev.sparteo.com:4444", - "page": "https://dev.sparteo.com:4444/page/test/", + "domain": "dev.sparteo.com", + "page": "https://dev.sparteo.com/page/test/", "publisher": { - "domain": "dev.sparteo.com:4444", + "domain": "dev.sparteo.com", "ext": { "params": { "networkId": "networkId" @@ -70,7 +70,7 @@ }, "id": "sparteo" }, - "ref": "https://dev.sparteo.com:4444/page/test/" + "ref": "https://dev.sparteo.com/page/test/" } }, "impIDs": [ diff --git a/adapters/sparteo/sparteotest/supplemental/status_204.json b/adapters/sparteo/sparteotest/supplemental/status_204.json index 171eec08ed..7358403bf6 100644 --- a/adapters/sparteo/sparteotest/supplemental/status_204.json +++ b/adapters/sparteo/sparteotest/supplemental/status_204.json @@ -19,12 +19,15 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com" + } }, "httpCalls": [ { "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&site_domain=dev.sparteo.com", "body": { "id": "request-id", "imp": [ @@ -47,7 +50,17 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com", + "publisher": { + "ext": { + "params": { + "networkId": "networkId" + } + } + } + } }, "impIDs": [ "div-banner-id" diff --git a/adapters/sparteo/sparteotest/supplemental/status_400.json b/adapters/sparteo/sparteotest/supplemental/status_400.json index 26f24b68be..d97b7f083c 100644 --- a/adapters/sparteo/sparteotest/supplemental/status_400.json +++ b/adapters/sparteo/sparteotest/supplemental/status_400.json @@ -19,12 +19,15 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com" + } }, "httpCalls": [ { "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&site_domain=dev.sparteo.com", "body": { "id": "request-id", "imp": [ @@ -47,7 +50,17 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com", + "publisher": { + "ext": { + "params": { + "networkId": "networkId" + } + } + } + } }, "impIDs": [ "div-banner-id" diff --git a/adapters/sparteo/sparteotest/supplemental/status_500.json b/adapters/sparteo/sparteotest/supplemental/status_500.json index ec3c68e56b..bee2affa48 100644 --- a/adapters/sparteo/sparteotest/supplemental/status_500.json +++ b/adapters/sparteo/sparteotest/supplemental/status_500.json @@ -19,12 +19,15 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com" + } }, "httpCalls": [ { "expectedRequest": { - "uri": "https://bid-test.sparteo.com/s2s-auction", + "uri": "https://bid-test.sparteo.com/s2s-auction?network_id=networkId&site_domain=dev.sparteo.com", "body": { "id": "request-id", "imp": [ @@ -47,7 +50,17 @@ } } } - ] + ], + "site": { + "domain": "dev.sparteo.com", + "publisher": { + "ext": { + "params": { + "networkId": "networkId" + } + } + } + } }, "impIDs": [ "div-banner-id" diff --git a/adapters/sspBC/sspbc.go b/adapters/sspBC/sspbc.go index 4a12ddaa51..36fce93ffc 100644 --- a/adapters/sspBC/sspbc.go +++ b/adapters/sspBC/sspbc.go @@ -7,12 +7,12 @@ import ( "net/url" "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/metrics" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/adapters/sspBC/sspbc_test.go b/adapters/sspBC/sspbc_test.go index f2fdc7dae6..a2a61f74c3 100644 --- a/adapters/sspBC/sspbc_test.go +++ b/adapters/sspBC/sspbc_test.go @@ -5,11 +5,11 @@ import ( "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/metrics" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/stackadapt/params_test.go b/adapters/stackadapt/params_test.go new file mode 100644 index 0000000000..25cac9a467 --- /dev/null +++ b/adapters/stackadapt/params_test.go @@ -0,0 +1,60 @@ +package stackadapt + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/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.BidderStackAdapt, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected stackadapt 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.BidderStackAdapt, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"publisherId":"pub-123","supplyId":"ssp-1"}`, + `{"publisherId":"pub-123","supplyId":"ssp-1","placementId":"placement-456"}`, + `{"publisherId":"pub-123","supplyId":"ssp-1","banner":{"expdir":[1,3]}}`, + `{"publisherId":"pub-123","supplyId":"ssp-1","bidfloor":1.5}`, + `{"publisherId":"pub-123","supplyId":"ssp-1","placementId":"pl-1","banner":{"expdir":[1,2,3]},"bidfloor":0.5}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `[]`, + `{}`, + `{"placementId":"placement-456"}`, + `{"publisherId":"pub-123"}`, + `{"supplyId":"ssp-1"}`, + `{"publisherId":""}`, + `{"publisherId":"pub-123","supplyId":""}`, + `{"publisherId":"pub-123","supplyId":"ssp-1","bidfloor":-1}`, + `{"publisherId":"pub-123","supplyId":"ssp-1","banner":"invalid"}`, + `{"publisherId":"pub-123","supplyId":"ssp-1","bidfloor":"high"}`, + `{"publisherId":"pub-123","supplyId":"ssp-1","banner":{"expdir":["a"]}}`, +} diff --git a/adapters/stackadapt/stackadapt.go b/adapters/stackadapt/stackadapt.go new file mode 100644 index 0000000000..925a3d7381 --- /dev/null +++ b/adapters/stackadapt/stackadapt.go @@ -0,0 +1,228 @@ +package stackadapt + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" + "text/template" + + "github.com/buger/jsonparser" + "github.com/prebid/openrtb/v20/adcom1" + "github.com/prebid/openrtb/v20/openrtb2" + + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint *template.Template +} + +func Builder(_ openrtb_ext.BidderName, cfg config.Adapter, _ config.Server) (adapters.Bidder, error) { + endpointTemplate, err := template.New("endpointTemplate").Parse(cfg.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %w", err) + } + return &adapter{ + endpoint: endpointTemplate, + }, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + // Imp level + publisherID, supplyID, err := setImpsAndGetEndpointParams(request) + if err != nil { + return nil, []error{err} + } + + // Request level + setPublisherID(request, publisherID) + + endpointURL, err := a.buildEndpointURL(publisherID, supplyID) + if err != nil { + return nil, []error{err} + } + + body, err := jsonutil.Marshal(request) + if err != nil { + return nil, []error{fmt.Errorf("marshal bidRequest: %w", err)} + } + + return []*adapters.RequestData{{ + Method: http.MethodPost, + Uri: endpointURL, + Body: body, + Headers: http.Header{ + "Content-Type": {"application/json;charset=utf-8"}, + "Accept": {"application/json"}, + }, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }}, nil +} + +func (a *adapter) buildEndpointURL(publisherID, supplyID string) (string, error) { + params := macros.EndpointTemplateParams{ + PublisherID: url.QueryEscape(publisherID), + SupplyId: url.QueryEscape(supplyID), + } + return macros.ResolveMacros(a.endpoint, params) +} + +func setImpsAndGetEndpointParams(request *openrtb2.BidRequest) (string, string, error) { + var publisherID, supplyID string + for i, imp := range request.Imp { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return "", "", &errortypes.BadInput{Message: fmt.Sprintf("imp[%d]: unable to unmarshal ext: %s", i, err.Error())} + } + + var saExt openrtb_ext.ExtImpStackAdapt + if err := jsonutil.Unmarshal(bidderExt.Bidder, &saExt); err != nil { + return "", "", &errortypes.BadInput{Message: fmt.Sprintf("imp[%d]: unable to unmarshal bidder ext: %s", i, err.Error())} + } + + if i == 0 { + publisherID = saExt.PublisherId + supplyID = saExt.SupplyId + } else if saExt.PublisherId != publisherID || saExt.SupplyId != supplyID { + return "", "", &errortypes.BadInput{Message: fmt.Sprintf("imp[%d]: all imps must have the same publisherId and supplyId", i)} + } + + if saExt.PlacementId != nil { + request.Imp[i].TagID = *saExt.PlacementId + } + + if saExt.BidFloor > 0 { + request.Imp[i].BidFloor = saExt.BidFloor + request.Imp[i].BidFloorCur = "USD" + } + + if saExt.Banner != nil && len(saExt.Banner.ExpDir) > 0 && request.Imp[i].Banner != nil { + bannerCopy := *request.Imp[i].Banner + bannerCopy.ExpDir = make([]adcom1.ExpandableDirection, len(saExt.Banner.ExpDir)) + for j, dir := range saExt.Banner.ExpDir { + bannerCopy.ExpDir[j] = adcom1.ExpandableDirection(dir) + } + request.Imp[i].Banner = &bannerCopy + } + } + + return publisherID, supplyID, nil +} + +func setPublisherID(request *openrtb2.BidRequest, publisherID string) { + if request.Site != nil { + siteCopy := *request.Site + if siteCopy.Publisher != nil { + publisherCopy := *siteCopy.Publisher + publisherCopy.ID = publisherID + siteCopy.Publisher = &publisherCopy + } else { + siteCopy.Publisher = &openrtb2.Publisher{ID: publisherID} + } + request.Site = &siteCopy + } else if request.App != nil { + appCopy := *request.App + if appCopy.Publisher != nil { + publisherCopy := *appCopy.Publisher + publisherCopy.ID = publisherID + appCopy.Publisher = &publisherCopy + } else { + appCopy.Publisher = &openrtb2.Publisher{ID: publisherID} + } + request.App = &appCopy + } +} + +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 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 errs []error + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bidType, err := getMediaTypeForBid(seatBid.Bid[i]) + if err != nil { + errs = append(errs, err) + continue + } + + if bidType == openrtb_ext.BidTypeNative { + seatBid.Bid[i].AdM, err = getNativeAdm(seatBid.Bid[i].AdM) + if err != nil { + errs = append(errs, err) + continue + } + } + resolveMacros(&seatBid.Bid[i]) + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + }) + } + } + + return bidResponse, errs +} + +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 + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("unsupported MType %d", bid.MType), + } + } +} + +func resolveMacros(bid *openrtb2.Bid) { + if bid == nil { + return + } + price := strconv.FormatFloat(bid.Price, 'f', -1, 64) + bid.AdM = strings.ReplaceAll(bid.AdM, "${AUCTION_PRICE}", price) + bid.NURL = strings.ReplaceAll(bid.NURL, "${AUCTION_PRICE}", price) + bid.BURL = strings.ReplaceAll(bid.BURL, "${AUCTION_PRICE}", price) +} + +func getNativeAdm(adm string) (string, error) { + value, dataType, _, err := jsonparser.Get([]byte(adm), string(openrtb_ext.BidTypeNative)) + if err != nil { + if errors.Is(err, jsonparser.KeyPathNotFoundError) { + return adm, nil + } + return adm, errors.New("unable to unmarshal native adm") + } + if dataType != jsonparser.Object { + return adm, errors.New("unable to get native adm") + } + return string(value), nil +} diff --git a/adapters/stackadapt/stackadapt_test.go b/adapters/stackadapt/stackadapt_test.go new file mode 100644 index 0000000000..de323de040 --- /dev/null +++ b/adapters/stackadapt/stackadapt_test.go @@ -0,0 +1,454 @@ +package stackadapt + +import ( + "encoding/json" + "net/http" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +const testsDir = "stackadapttest" +const testsBidderEndpoint = "http://localhost/br?publisher_id={{.PublisherID}}&supply_id={{.SupplyId}}" + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder( + openrtb_ext.BidderStackAdapt, + config.Adapter{Endpoint: testsBidderEndpoint}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, testsDir, bidder) +} + +func TestGetMediaTypeForBid(t *testing.T) { + tests := []struct { + name string + mtype openrtb2.MarkupType + expectedType openrtb_ext.BidType + wantErr bool + }{ + {name: "banner", mtype: 1, expectedType: openrtb_ext.BidTypeBanner}, + {name: "video", mtype: 2, expectedType: openrtb_ext.BidTypeVideo}, + {name: "audio", mtype: 3, expectedType: openrtb_ext.BidTypeAudio}, + {name: "native", mtype: 4, expectedType: openrtb_ext.BidTypeNative}, + {name: "zero", mtype: 0, expectedType: "", wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bidType, err := getMediaTypeForBid(openrtb2.Bid{MType: tt.mtype}) + if tt.wantErr { + assert.Error(t, err) + assert.Empty(t, bidType) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expectedType, bidType) + } + }) + } +} + +func TestResolveMacros(t *testing.T) { + tests := []struct { + name string + bid *openrtb2.Bid + expectedAdM string + expectedNURL string + expectedBURL string + }{ + { + name: "nil_bid", + bid: nil, + }, + { + name: "replaces_in_all_fields", + bid: &openrtb2.Bid{ + Price: 2.50, + AdM: "price=${AUCTION_PRICE}", + NURL: "http://win?p=${AUCTION_PRICE}", + BURL: "http://bill?p=${AUCTION_PRICE}", + }, + expectedAdM: "price=2.5", + expectedNURL: "http://win?p=2.5", + expectedBURL: "http://bill?p=2.5", + }, + { + name: "multiple_macros_same_field", + bid: &openrtb2.Bid{ + Price: 1.00, + AdM: "${AUCTION_PRICE}+${AUCTION_PRICE}", + }, + expectedAdM: "1+1", + }, + { + name: "no_macros", + bid: &openrtb2.Bid{ + Price: 5.00, + AdM: "
ad
", + NURL: "http://example.com", + }, + expectedAdM: "
ad
", + expectedNURL: "http://example.com", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resolveMacros(tt.bid) + if tt.bid == nil { + return + } + assert.Equal(t, tt.expectedAdM, tt.bid.AdM) + assert.Equal(t, tt.expectedNURL, tt.bid.NURL) + assert.Equal(t, tt.expectedBURL, tt.bid.BURL) + }) + } +} + +func TestGetNativeAdm(t *testing.T) { + tests := []struct { + name string + adm string + expectedAdm string + wantErr bool + }{ + { + name: "unwraps_native_envelope", + adm: `{"native":{"link":{"url":"https://example.com"},"assets":[{"id":1,"title":{"text":"Title"}}]}}`, + expectedAdm: `{"link":{"url":"https://example.com"},"assets":[{"id":1,"title":{"text":"Title"}}]}`, + }, + { + name: "already_unwrapped", + adm: `{"link":{"url":"https://example.com"},"assets":[{"id":1,"title":{"text":"Title"}}]}`, + expectedAdm: `{"link":{"url":"https://example.com"},"assets":[{"id":1,"title":{"text":"Title"}}]}`, + }, + { + name: "no_native_key_passthrough", + adm: `not json`, + expectedAdm: `not json`, + }, + { + name: "malformed_native_envelope", + adm: `{"native":`, + wantErr: true, + }, + { + name: "native_key_not_object", + adm: `{"native":"string_value"}`, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := getNativeAdm(tt.adm) + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expectedAdm, result) + } + }) + } +} + +func TestSetPublisherID(t *testing.T) { + t.Run("site_without_publisher", func(t *testing.T) { + req := &openrtb2.BidRequest{Site: &openrtb2.Site{Page: "https://example.com"}} + setPublisherID(req, "pub-1") + assert.Equal(t, "pub-1", req.Site.Publisher.ID) + }) + + t.Run("site_with_existing_publisher", func(t *testing.T) { + req := &openrtb2.BidRequest{Site: &openrtb2.Site{ + Page: "https://example.com", + Publisher: &openrtb2.Publisher{ID: "old", Name: "OldPub"}, + }} + setPublisherID(req, "pub-2") + assert.Equal(t, "pub-2", req.Site.Publisher.ID) + assert.Equal(t, "OldPub", req.Site.Publisher.Name) + }) + + t.Run("app_without_publisher", func(t *testing.T) { + req := &openrtb2.BidRequest{App: &openrtb2.App{Bundle: "com.example"}} + setPublisherID(req, "app-pub-1") + assert.Equal(t, "app-pub-1", req.App.Publisher.ID) + }) + + t.Run("app_with_existing_publisher", func(t *testing.T) { + req := &openrtb2.BidRequest{App: &openrtb2.App{ + Bundle: "com.example", + Publisher: &openrtb2.Publisher{ID: "old", Name: "OldAppPub"}, + }} + setPublisherID(req, "app-pub-2") + assert.Equal(t, "app-pub-2", req.App.Publisher.ID) + assert.Equal(t, "OldAppPub", req.App.Publisher.Name) + }) + + t.Run("site_takes_precedence_over_app", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Site: &openrtb2.Site{Page: "https://example.com"}, + App: &openrtb2.App{Bundle: "com.example"}, + } + setPublisherID(req, "pub-site") + assert.Equal(t, "pub-site", req.Site.Publisher.ID) + assert.Nil(t, req.App.Publisher) + }) + + t.Run("no_site_or_app", func(t *testing.T) { + req := &openrtb2.BidRequest{} + setPublisherID(req, "pub-1") + assert.Nil(t, req.Site) + assert.Nil(t, req.App) + }) +} + +func TestSetImpsAndGetEndpointParams(t *testing.T) { + t.Run("valid_with_all_params", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ + Banner: &openrtb2.Banner{}, + Ext: json.RawMessage(`{"bidder":{"publisherId":"pub-1","supplyId":"ssp-1","placementId":"pl-1","bidfloor":1.5,"banner":{"expdir":[1,3]}}}`), + }}, + } + pubID, supplyID, err := setImpsAndGetEndpointParams(req) + assert.NoError(t, err) + assert.Equal(t, "pub-1", pubID) + assert.Equal(t, "ssp-1", supplyID) + assert.Equal(t, "pl-1", req.Imp[0].TagID) + assert.Equal(t, 1.5, req.Imp[0].BidFloor) + assert.Equal(t, "USD", req.Imp[0].BidFloorCur) + assert.Len(t, req.Imp[0].Banner.ExpDir, 2) + }) + + t.Run("publisher_id_and_supply_id", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ + Ext: json.RawMessage(`{"bidder":{"publisherId":"pub-2","supplyId":"ssp-2"}}`), + }}, + } + pubID, supplyID, err := setImpsAndGetEndpointParams(req) + assert.NoError(t, err) + assert.Equal(t, "pub-2", pubID) + assert.Equal(t, "ssp-2", supplyID) + assert.Empty(t, req.Imp[0].TagID) + assert.Zero(t, req.Imp[0].BidFloor) + }) + + t.Run("invalid_ext_json", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ + Ext: json.RawMessage(`{invalid`), + }}, + } + _, _, err := setImpsAndGetEndpointParams(req) + assert.Error(t, err) + assert.Contains(t, err.Error(), "unable to unmarshal ext") + }) + + t.Run("invalid_bidder_ext_json", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ + Ext: json.RawMessage(`{"bidder":"not-an-object"}`), + }}, + } + _, _, err := setImpsAndGetEndpointParams(req) + assert.Error(t, err) + assert.Contains(t, err.Error(), "unable to unmarshal bidder ext") + }) + + t.Run("multi_imp_same_publisher_id_and_supply_id", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {Ext: json.RawMessage(`{"bidder":{"publisherId":"pub-1","supplyId":"ssp-1"}}`)}, + {Ext: json.RawMessage(`{"bidder":{"publisherId":"pub-1","supplyId":"ssp-1"}}`)}, + }, + } + pubID, supplyID, err := setImpsAndGetEndpointParams(req) + assert.NoError(t, err) + assert.Equal(t, "pub-1", pubID) + assert.Equal(t, "ssp-1", supplyID) + }) + + t.Run("multi_imp_mismatched_publisher_id_or_supply_id", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {Ext: json.RawMessage(`{"bidder":{"publisherId":"pub-1","supplyId":"ssp-1"}}`)}, + {Ext: json.RawMessage(`{"bidder":{"publisherId":"pub-2","supplyId":"ssp-1"}}`)}, + }, + } + _, _, err := setImpsAndGetEndpointParams(req) + assert.Error(t, err) + assert.Contains(t, err.Error(), "all imps must have the same publisherId and supplyId") + }) + + t.Run("zero_bidfloor_not_set", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ + Ext: json.RawMessage(`{"bidder":{"publisherId":"pub-1","supplyId":"ssp-1","bidfloor":0}}`), + }}, + } + _, _, err := setImpsAndGetEndpointParams(req) + assert.NoError(t, err) + assert.Zero(t, req.Imp[0].BidFloor) + assert.Empty(t, req.Imp[0].BidFloorCur) + }) + + t.Run("expdir_ignored_without_banner", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ + Ext: json.RawMessage(`{"bidder":{"publisherId":"pub-1","supplyId":"ssp-1","banner":{"expdir":[1,2]}}}`), + }}, + } + _, _, err := setImpsAndGetEndpointParams(req) + assert.NoError(t, err) + assert.Nil(t, req.Imp[0].Banner) + }) +} + +func TestMakeRequests(t *testing.T) { + a, err := Builder(openrtb_ext.BidderStackAdapt, config.Adapter{Endpoint: testsBidderEndpoint}, config.Server{}) + assert.NoError(t, err) + + t.Run("site_request", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{Ext: json.RawMessage(`{"bidder":{"publisherId":"pub-1","supplyId":"ssp-1"}}`)}}, + Site: &openrtb2.Site{Page: "https://example.com"}, + } + data, errs := a.MakeRequests(req, nil) + assert.Empty(t, errs) + assert.Len(t, data, 1) + assert.Equal(t, http.MethodPost, data[0].Method) + assert.Equal(t, "http://localhost/br?publisher_id=pub-1&supply_id=ssp-1", data[0].Uri) + }) + + t.Run("app_request", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{Ext: json.RawMessage(`{"bidder":{"publisherId":"pub-1","supplyId":"ssp-1"}}`)}}, + App: &openrtb2.App{Bundle: "com.example"}, + } + data, errs := a.MakeRequests(req, nil) + assert.Empty(t, errs) + assert.Len(t, data, 1) + + var body openrtb2.BidRequest + assert.NoError(t, json.Unmarshal(data[0].Body, &body)) + assert.Equal(t, "pub-1", body.App.Publisher.ID) + assert.Equal(t, "http://localhost/br?publisher_id=pub-1&supply_id=ssp-1", data[0].Uri) + }) + + t.Run("invalid_bidder_ext_returns_error", func(t *testing.T) { + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{Ext: json.RawMessage(`{"bidder":"not-an-object"}`)}}, + Site: &openrtb2.Site{}, + } + data, errs := a.MakeRequests(req, nil) + assert.Nil(t, data) + assert.Len(t, errs, 1) + assert.Contains(t, errs[0].Error(), "unable to unmarshal bidder ext") + }) +} + +func TestBuildEndpointURL(t *testing.T) { + endpointTemplate := "http://localhost/br?publisher_id={{.PublisherID}}&supply_id={{.SupplyId}}" + a, err := Builder(openrtb_ext.BidderStackAdapt, config.Adapter{Endpoint: endpointTemplate}, config.Server{}) + assert.NoError(t, err) + + req := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{Ext: json.RawMessage(`{"bidder":{"publisherId":"test-pub","supplyId":"test-ssp"}}`)}}, + Site: &openrtb2.Site{}, + } + data, errs := a.MakeRequests(req, nil) + assert.Empty(t, errs) + assert.Len(t, data, 1) + assert.Equal(t, "http://localhost/br?publisher_id=test-pub&supply_id=test-ssp", data[0].Uri) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderStackAdapt, config.Adapter{ + Endpoint: "{{Malformed}}", + }, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + assert.Error(t, buildErr) +} + +func TestMakeBids(t *testing.T) { + a, err := Builder(openrtb_ext.BidderStackAdapt, + config.Adapter{Endpoint: testsBidderEndpoint}, config.Server{}) + assert.NoError(t, err) + + t.Run("204_no_content", func(t *testing.T) { + resp, errs := a.MakeBids(nil, nil, &adapters.ResponseData{StatusCode: http.StatusNoContent}) + assert.Nil(t, resp) + assert.Nil(t, errs) + }) + + t.Run("500_server_error", func(t *testing.T) { + resp, errs := a.MakeBids(nil, nil, &adapters.ResponseData{StatusCode: http.StatusInternalServerError}) + assert.Nil(t, resp) + assert.Len(t, errs, 1) + }) + + t.Run("valid_banner_bid", func(t *testing.T) { + resp, errs := a.MakeBids( + &openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "imp-1"}}}, + nil, + &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{"cur":"USD","seatbid":[{"bid":[{"id":"bid-1","impid":"imp-1","price":1.5,"adm":"
ad
","mtype":1}]}]}`), + }, + ) + assert.Nil(t, errs) + assert.Len(t, resp.Bids, 1) + assert.Equal(t, openrtb_ext.BidTypeBanner, resp.Bids[0].BidType) + assert.Equal(t, "USD", resp.Currency) + }) + + t.Run("unsupported_mtype_skipped", func(t *testing.T) { + resp, errs := a.MakeBids( + &openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "imp-1"}}}, + nil, + &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{"seatbid":[{"bid":[{"id":"bid-1","impid":"imp-1","price":1.0,"mtype":99}]}]}`), + }, + ) + assert.Len(t, errs, 1) + assert.Empty(t, resp.Bids) + }) + + t.Run("native_unwrap_and_macro_resolution", func(t *testing.T) { + nativeAdm := `{"native":{"link":{"url":"https://example.com/click"},"assets":[{"id":1,"title":{"text":"Title"}}],"imptrackers":["https://example.com/imp?p=${AUCTION_PRICE}"]}}` + body := `{"seatbid":[{"bid":[{"id":"bid-1","impid":"imp-1","price":3.5,"adm":` + mustMarshalString(nativeAdm) + `,"mtype":4}]}]}` + + resp, errs := a.MakeBids( + &openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "imp-1"}}}, + nil, + &adapters.ResponseData{StatusCode: http.StatusOK, Body: []byte(body)}, + ) + assert.Nil(t, errs) + assert.Len(t, resp.Bids, 1) + assert.Equal(t, openrtb_ext.BidTypeNative, resp.Bids[0].BidType) + assert.NotContains(t, resp.Bids[0].Bid.AdM, `"native"`) + assert.NotContains(t, resp.Bids[0].Bid.AdM, "${AUCTION_PRICE}") + }) + + t.Run("invalid_response_body", func(t *testing.T) { + resp, errs := a.MakeBids( + &openrtb2.BidRequest{}, + nil, + &adapters.ResponseData{StatusCode: http.StatusOK, Body: []byte(`not json`)}, + ) + assert.Nil(t, resp) + assert.Len(t, errs, 1) + }) +} + +func mustMarshalString(s string) string { + b, _ := json.Marshal(s) + return string(b) +} diff --git a/adapters/stackadapt/stackadapttest/exemplary/app-banner.json b/adapters/stackadapt/stackadapttest/exemplary/app-banner.json new file mode 100644 index 0000000000..7a4ab2487f --- /dev/null +++ b/adapters/stackadapt/stackadapttest/exemplary/app-banner.json @@ -0,0 +1,93 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 320, + "h": 50 + }] + }, + "ext": { + "bidder": { + "publisherId": "app-pub-1", + "supplyId": "ssp-1", + "placementId": "app-pl-1" + } + } + }], + "app": { + "bundle": "com.example.app", + "name": "Example App" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=app-pub-1&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 320, + "h": 50 + }] + }, + "tagid": "app-pl-1", + "ext": { + "bidder": { + "publisherId": "app-pub-1", + "supplyId": "ssp-1", + "placementId": "app-pl-1" + } + } + }], + "app": { + "bundle": "com.example.app", + "name": "Example App", + "publisher": { + "id": "app-pub-1" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.50, + "adm": "
mobile-ad
", + "crid": "creative-mob-1", + "w": 320, + "h": 50, + "mtype": 1 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.5, + "adm": "
mobile-ad
", + "crid": "creative-mob-1", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + }] + }] +} \ No newline at end of file diff --git a/adapters/stackadapt/stackadapttest/exemplary/multi-imp.json b/adapters/stackadapt/stackadapttest/exemplary/multi-imp.json new file mode 100644 index 0000000000..0e721b10c8 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/exemplary/multi-imp.json @@ -0,0 +1,179 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }, + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1", + "placementId": "pl-1", + "banner": { + "expdir": [1, 3] + }, + "bidfloor": 1.5 + } + } + }, + { + "id": "test-imp-id-2", + "video": { + "mimes": ["video/mp4"], + "minduration": 5, + "maxduration": 30, + "protocols": [1, 2], + "w": 1920, + "h": 1080, + "api": [1, 2] + }, + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1" + } + } + } + ], + "site": { + "page": "https://example.com/page" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=123&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }, + { + "w": 728, + "h": 90 + } + ], + "expdir": [1, 3] + }, + "tagid": "pl-1", + "bidfloor": 1.5, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1", + "placementId": "pl-1", + "banner": { + "expdir": [1, 3] + }, + "bidfloor": 1.5 + } + } + }, + { + "id": "test-imp-id-2", + "video": { + "mimes": ["video/mp4"], + "minduration": 5, + "maxduration": 30, + "protocols": [1, 2], + "w": 1920, + "h": 1080, + "api": [1, 2] + }, + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1" + } + } + } + ], + "site": { + "page": "https://example.com/page", + "publisher": { + "id": "123" + } + } + }, + "impIDs": ["test-imp-id", "test-imp-id-2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.50, + "adm": "
test-ad
", + "adid": "ad-123", + "crid": "creative-123", + "w": 300, + "h": 250, + "mtype": 1 + }] + }, + { + "bid": [{ + "id": "test-bid-id-2", + "impid": "test-imp-id-2", + "price": 5.00, + "adm": "", + "crid": "creative-456", + "w": 640, + "h": 480, + "mtype": 2 + }] + } + ] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
test-ad
", + "adid": "ad-123", + "crid": "creative-123", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "test-bid-id-2", + "impid": "test-imp-id-2", + "price": 5.00, + "adm": "", + "crid": "creative-456", + "w": 640, + "h": 480, + "mtype": 2 + }, + "type": "video" + } + ] + }] +} \ No newline at end of file diff --git a/adapters/stackadapt/stackadapttest/exemplary/simple-web-audio.json b/adapters/stackadapt/stackadapttest/exemplary/simple-web-audio.json new file mode 100644 index 0000000000..3761f08994 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/exemplary/simple-web-audio.json @@ -0,0 +1,84 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "audio": { + "mimes": ["audio/mp4", "audio/mpeg", "audio/ogg"], + "minduration": 5, + "maxduration": 30, + "protocols": [3, 6, 2, 5, 7, 8] + }, + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/audio" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=123&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "audio": { + "mimes": ["audio/mp4", "audio/mpeg", "audio/ogg"], + "minduration": 5, + "maxduration": 30, + "protocols": [3, 6, 2, 5, 7, 8] + }, + "ext": { +"bidder": { + "publisherId": "123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/audio", + "publisher": { + "id": "123" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 4.00, + "adm": "StackAdapt00:00:14https://example.com/audio.mp4", + "crid": "creative-101", + "mtype": 3 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 4, + "adm": "StackAdapt00:00:14https://example.com/audio.mp4", + "crid": "creative-101", + "mtype": 3 + }, + "type": "audio" + }] + }] +} \ No newline at end of file diff --git a/adapters/stackadapt/stackadapttest/exemplary/simple-web-banner.json b/adapters/stackadapt/stackadapttest/exemplary/simple-web-banner.json new file mode 100644 index 0000000000..852e1e30b1 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/exemplary/simple-web-banner.json @@ -0,0 +1,114 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }, + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1", + "placementId": "pl-1", + "banner": { + "expdir": [1, 3] + }, + "bidfloor": 1.5 + } + } + }], + "site": { + "page": "https://example.com/page" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=123&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }, + { + "w": 728, + "h": 90 + } + ], + "expdir": [1, 3] + }, + "tagid": "pl-1", + "bidfloor": 1.5, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1", + "placementId": "pl-1", + "banner": { + "expdir": [1, 3] + }, + "bidfloor": 1.5 + } + } + }], + "site": { + "page": "https://example.com/page", + "publisher": { + "id": "123" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.50, + "adm": "
test-ad
", + "adid": "ad-123", + "crid": "creative-123", + "w": 300, + "h": 250, + "mtype": 1 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
test-ad
", + "adid": "ad-123", + "crid": "creative-123", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + }] + }] +} \ No newline at end of file diff --git a/adapters/stackadapt/stackadapttest/exemplary/simple-web-native.json b/adapters/stackadapt/stackadapttest/exemplary/simple-web-native.json new file mode 100644 index 0000000000..0b961d7eac --- /dev/null +++ b/adapters/stackadapt/stackadapttest/exemplary/simple-web-native.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.1\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":90}},{\"id\":2,\"required\":0,\"data\":{\"type\":2,\"len\":140}},{\"id\":3,\"required\":1,\"img\":{\"type\":3,\"w\":1200,\"h\":627}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=123&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.1\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":90}},{\"id\":2,\"required\":0,\"data\":{\"type\":2,\"len\":140}},{\"id\":3,\"required\":1,\"img\":{\"type\":3,\"w\":1200,\"h\":627}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page", + "publisher": { + "id": "123" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.00, + "adm": "{\"native\":{\"link\":{\"url\":\"https://example.com/click\"},\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Title\"}},{\"id\":2,\"img\":{\"url\":\"https://example.com/image.jpg\",\"w\":1200,\"h\":627}}],\"imptrackers\":[\"https://example.com/imp\"]}}", + "crid": "creative-789", + "mtype": 4 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3, + "adm": "{\"link\":{\"url\":\"https://example.com/click\"},\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Title\"}},{\"id\":2,\"img\":{\"url\":\"https://example.com/image.jpg\",\"w\":1200,\"h\":627}}],\"imptrackers\":[\"https://example.com/imp\"]}", + "crid": "creative-789", + "mtype": 4 + }, + "type": "native" + }] + }] +} \ No newline at end of file diff --git a/adapters/stackadapt/stackadapttest/exemplary/simple-web-video.json b/adapters/stackadapt/stackadapttest/exemplary/simple-web-video.json new file mode 100644 index 0000000000..ad7e8d8764 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/exemplary/simple-web-video.json @@ -0,0 +1,94 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 5, + "maxduration": 30, + "protocols": [1, 2], + "w": 640, + "h": 480, + "api": [1, 2] + }, + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/video" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=123&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 5, + "maxduration": 30, + "protocols": [1, 2], + "w": 640, + "h": 480, + "api": [1, 2] + }, + "ext": { +"bidder": { + "publisherId": "123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/video", + "publisher": { + "id": "123" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 5.00, + "adm": "", + "crid": "creative-456", + "w": 640, + "h": 480, + "mtype": 2 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 5, + "adm": "", + "crid": "creative-456", + "w": 640, + "h": 480, + "mtype": 2 + }, + "type": "video" + }] + }] +} \ No newline at end of file diff --git a/adapters/stackadapt/stackadapttest/supplemental/app-with-existing-publisher.json b/adapters/stackadapt/stackadapttest/supplemental/app-with-existing-publisher.json new file mode 100644 index 0000000000..bccb4ef0d8 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/supplemental/app-with-existing-publisher.json @@ -0,0 +1,95 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 320, + "h": 50 + }] + }, + "ext": { + "bidder": { + "publisherId": "app-pub-new", + "supplyId": "ssp-1" + } + } + }], + "app": { + "bundle": "com.example.app", + "name": "Example App", + "publisher": { + "id": "app-pub-old", + "name": "Existing App Publisher" + } + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=app-pub-new&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 320, + "h": 50 + }] + }, + "ext": { + "bidder": { + "publisherId": "app-pub-new", + "supplyId": "ssp-1" + } + } + }], + "app": { + "bundle": "com.example.app", + "name": "Example App", + "publisher": { + "id": "app-pub-new", + "name": "Existing App Publisher" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.5, + "adm": "
app-ad
", + "crid": "creative-app-1", + "w": 320, + "h": 50, + "mtype": 1 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 2.5, + "adm": "
app-ad
", + "crid": "creative-app-1", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + }] + }] +} diff --git a/adapters/stackadapt/stackadapttest/supplemental/auction-price-macro.json b/adapters/stackadapt/stackadapttest/supplemental/auction-price-macro.json new file mode 100644 index 0000000000..2e5316b457 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/supplemental/auction-price-macro.json @@ -0,0 +1,92 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=123&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page", + "publisher": { + "id": "123" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.50, + "adm": "
ad with price ${AUCTION_PRICE}
", + "nurl": "https://example.com/win?price=${AUCTION_PRICE}", + "burl": "https://example.com/billing?price=${AUCTION_PRICE}", + "crid": "creative-macro-1", + "w": 300, + "h": 250, + "mtype": 1 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.5, + "adm": "
ad with price 3.5
", + "nurl": "https://example.com/win?price=3.5", + "burl": "https://example.com/billing?price=3.5", + "crid": "creative-macro-1", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + }] + }] +} \ No newline at end of file diff --git a/adapters/stackadapt/stackadapttest/supplemental/bad-bidder-ext.json b/adapters/stackadapt/stackadapttest/supplemental/bad-bidder-ext.json new file mode 100644 index 0000000000..d0f5d3f218 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/supplemental/bad-bidder-ext.json @@ -0,0 +1,24 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": "invalid-not-an-object" + } + }], + "site": { + "page": "https://example.com/page" + } + }, + "expectedMakeRequestsErrors": [{ + "value": "imp[0]: unable to unmarshal bidder ext", + "comparison": "startswith" + }] +} \ No newline at end of file diff --git a/adapters/stackadapt/stackadapttest/supplemental/endpoint-param-escaping.json b/adapters/stackadapt/stackadapttest/supplemental/endpoint-param-escaping.json new file mode 100644 index 0000000000..df261cd7b3 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/supplemental/endpoint-param-escaping.json @@ -0,0 +1,58 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "pub&123", + "supplyId": "ssp 1" + } + } + }], + "site": { + "page": "https://example.com/page" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=pub%26123&supply_id=ssp+1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "pub&123", + "supplyId": "ssp 1" + } + } + }], + "site": { + "page": "https://example.com/page", + "publisher": { + "id": "pub&123" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + }], + "expectedBidResponses": [] +} diff --git a/adapters/stackadapt/stackadapttest/supplemental/multi-imp-mismatch.json b/adapters/stackadapt/stackadapttest/supplemental/multi-imp-mismatch.json new file mode 100644 index 0000000000..d03fc97a0e --- /dev/null +++ b/adapters/stackadapt/stackadapttest/supplemental/multi-imp-mismatch.json @@ -0,0 +1,43 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "123", + "supplyId": "ssp-1" + } + } + }, + { + "id": "test-imp-id-2", + "banner": { + "format": [{ + "w": 728, + "h": 90 + }] + }, + "ext": { + "bidder": { + "publisherId": "456", + "supplyId": "ssp-1" + } + } + } + ], + "site": { + "page": "https://example.com/page" + } + }, + "expectedMakeRequestsErrors": [{ + "value": "imp[1]: all imps must have the same publisherId and supplyId", + "comparison": "literal" + }] +} diff --git a/adapters/stackadapt/stackadapttest/supplemental/native-adm-invalid.json b/adapters/stackadapt/stackadapttest/supplemental/native-adm-invalid.json new file mode 100644 index 0000000000..725f69003f --- /dev/null +++ b/adapters/stackadapt/stackadapttest/supplemental/native-adm-invalid.json @@ -0,0 +1,74 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.1\"}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "publisherId": "pub-123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=pub-123&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.1\"}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "publisherId": "pub-123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page", + "publisher": { + "id": "pub-123" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.50, + "adm": "{\"native\":\"not-an-object\"}", + "crid": "creative-123", + "mtype": 4 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [] + }], + "expectedMakeBidsErrors": [{ + "value": "unable to get native adm", + "comparison": "literal" + }] +} diff --git a/adapters/stackadapt/stackadapttest/supplemental/no-content.json b/adapters/stackadapt/stackadapttest/supplemental/no-content.json new file mode 100644 index 0000000000..90b21a4a38 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/supplemental/no-content.json @@ -0,0 +1,58 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "pub-123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=pub-123&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "pub-123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page", + "publisher": { + "id": "pub-123" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + }], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/stackadapt/stackadapttest/supplemental/site-with-existing-publisher.json b/adapters/stackadapt/stackadapttest/supplemental/site-with-existing-publisher.json new file mode 100644 index 0000000000..1ab79a6338 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/supplemental/site-with-existing-publisher.json @@ -0,0 +1,93 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "pub-new", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page", + "publisher": { + "id": "pub-old", + "name": "Existing Publisher Name" + } + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=pub-new&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "pub-new", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page", + "publisher": { + "id": "pub-new", + "name": "Existing Publisher Name" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.50, + "adm": "
ad
", + "crid": "creative-123", + "w": 300, + "h": 250, + "mtype": 1 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
ad
", + "crid": "creative-123", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + }] + }] +} diff --git a/adapters/stackadapt/stackadapttest/supplemental/status-400.json b/adapters/stackadapt/stackadapttest/supplemental/status-400.json new file mode 100644 index 0000000000..7c8c554391 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/supplemental/status-400.json @@ -0,0 +1,61 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "pub-123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=pub-123&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "pub-123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page", + "publisher": { + "id": "pub-123" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 400, + "body": {} + } + }], + "expectedMakeBidsErrors": [{ + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + }] +} diff --git a/adapters/stackadapt/stackadapttest/supplemental/unsupported-mtype.json b/adapters/stackadapt/stackadapttest/supplemental/unsupported-mtype.json new file mode 100644 index 0000000000..e2a24c7728 --- /dev/null +++ b/adapters/stackadapt/stackadapttest/supplemental/unsupported-mtype.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "pub-123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/br?publisher_id=pub-123&supply_id=ssp-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisherId": "pub-123", + "supplyId": "ssp-1" + } + } + }], + "site": { + "page": "https://example.com/page", + "publisher": { + "id": "pub-123" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.50, + "adm": "some-ad", + "crid": "creative-123", + "w": 300, + "h": 250, + "mtype": 99 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [] + }], + "expectedMakeBidsErrors": [{ + "value": "unsupported MType 99", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/startio/startio.go b/adapters/startio/startio.go index b524a66013..6699ab8ee3 100644 --- a/adapters/startio/startio.go +++ b/adapters/startio/startio.go @@ -6,11 +6,11 @@ import ( "slices" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/startio/startio_test.go b/adapters/startio/startio_test.go index 8de9e017ad..5aa321e63f 100644 --- a/adapters/startio/startio_test.go +++ b/adapters/startio/startio_test.go @@ -3,9 +3,9 @@ package startio 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/stroeerCore/params_test.go b/adapters/stroeerCore/params_test.go index 4050a21959..6aa2d02d7d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/stroeerCore/stroeercore.go b/adapters/stroeerCore/stroeercore.go index 57dc2b0cd7..236980fde1 100644 --- a/adapters/stroeerCore/stroeercore.go +++ b/adapters/stroeerCore/stroeercore.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { @@ -32,12 +32,10 @@ type bidResponse struct { Ad string `json:"ad"` CrID string `json:"crid"` Mtype string `json:"mtype"` - DSA json.RawMessage `json:"dsa"` ADomain []string `json:"adomain,omitempty"` -} - -type bidExt struct { - DSA json.RawMessage `json:"dsa,omitempty"` + Ext json.RawMessage `json:"ext,omitempty"` + // Deprecated: The dsa will move to the bid response's ext. + DSA json.RawMessage `json:"dsa"` } func (b *bidResponse) resolveMediaType() (mt openrtb2.MarkupType, bt openrtb_ext.BidType, err error) { @@ -88,15 +86,7 @@ func (a *adapter) MakeBids(bidRequest *openrtb2.BidRequest, requestData *adapter CrID: bid.CrID, MType: markupType, ADomain: bid.ADomain, - } - - if bid.DSA != nil { - dsaJson, err := json.Marshal(bidExt{bid.DSA}) - if err != nil { - errors = append(errors, err) - } else { - openRtbBid.Ext = dsaJson - } + Ext: getBidExt(bid), } bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{ @@ -108,6 +98,19 @@ func (a *adapter) MakeBids(bidRequest *openrtb2.BidRequest, requestData *adapter return bidderResponse, errors } +func getBidExt(bid bidResponse) json.RawMessage { + if bid.DSA == nil { + return bid.Ext + } + extMap := map[string]json.RawMessage{} + if bid.Ext != nil { + _ = jsonutil.Unmarshal(bid.Ext, &extMap) + } + extMap["dsa"] = bid.DSA + ext, _ := json.Marshal(extMap) + return ext +} + func (a *adapter) MakeRequests(bidRequest *openrtb2.BidRequest, extraRequestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { var errors []error diff --git a/adapters/stroeerCore/stroeercore_test.go b/adapters/stroeerCore/stroeercore_test.go index b0f6204880..4040b34156 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/stroeerCore/stroeercoretest/exemplary/bid-ext.json b/adapters/stroeerCore/stroeercoretest/exemplary/bid-ext.json new file mode 100644 index 0000000000..43e997e25b --- /dev/null +++ b/adapters/stroeerCore/stroeercoretest/exemplary/bid-ext.json @@ -0,0 +1,207 @@ +{ + "mockBidRequest": { + "id": "auction-id", + "cur": [ + "EUR" + ], + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "sid": "123456" + } + } + } + ], + "device": { + "ip": "123.123.123.123" + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path" + }, + "user": { + "buyeruid": "test-buyer-user-id" + }, + "regs": { + "ext": { + "dsa": { + "dsarequired": 3, + "pubrender": 0, + "datatopub": 2, + "transparency": [ + { + "domain": "example-platform.com", + "dsaparams": [ + 1 + ] + }, + { + "domain": "example-ssp.com", + "dsaparams": [ + 1, + 2 + ] + } + ] + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "uri": "http://localhost/s2sdsh", + "body": { + "id": "auction-id", + "cur": [ + "EUR" + ], + "imp": [ + { + "id": "1", + "tagid": "123456", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "sid": "123456" + } + } + } + ], + "device": { + "ip": "123.123.123.123" + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path" + }, + "user": { + "buyeruid": "test-buyer-user-id" + }, + "regs": { + "ext": { + "dsa": { + "dsarequired": 3, + "pubrender": 0, + "datatopub": 2, + "transparency": [ + { + "domain": "example-platform.com", + "dsaparams": [ + 1 + ] + }, + { + "domain": "example-ssp.com", + "dsaparams": [ + 1, + 2 + ] + } + ] + } + } + } + }, + "impIDs":["1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "bids": [ + { + "id": "1829273982920-01", + "bidId": "1", + "cpm": 2, + "width": 300, + "height": 600, + "ad": "advert", + "crid": "wasd", + "mtype": "banner", + "ext": { + "other": "thing", + "dsa": { + "behalf": "Advertiser A", + "paid": "Advertiser B", + "transparency": [ + { + "domain": "example-domain.com", + "dsaparams": [ + 1, + 2 + ] + } + ], + "adrender": 1 + } + } + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "1829273982920-01", + "impid": "1", + "price": 2, + "adm": "advert", + "w": 300, + "h": 600, + "crid": "wasd", + "mtype": 1, + "ext": { + "other": "thing", + "dsa": { + "behalf": "Advertiser A", + "paid": "Advertiser B", + "transparency": [ + { + "domain": "example-domain.com", + "dsaparams": [ + 1, + 2 + ] + } + ], + "adrender": 1 + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/stroeerCore/stroeercoretest/exemplary/dsa.json b/adapters/stroeerCore/stroeercoretest/exemplary/deprecated-json-path-for-dsa.json similarity index 97% rename from adapters/stroeerCore/stroeercoretest/exemplary/dsa.json rename to adapters/stroeerCore/stroeercoretest/exemplary/deprecated-json-path-for-dsa.json index 97355da905..b2c21511d5 100644 --- a/adapters/stroeerCore/stroeercoretest/exemplary/dsa.json +++ b/adapters/stroeerCore/stroeercoretest/exemplary/deprecated-json-path-for-dsa.json @@ -157,6 +157,9 @@ } ], "adrender": 1 + }, + "ext": { + "something": "else" } } ] @@ -192,7 +195,8 @@ } ], "adrender": 1 - } + }, + "something": "else" } }, "type": "banner" diff --git a/adapters/synapseHX/params_test.go b/adapters/synapseHX/params_test.go new file mode 100644 index 0000000000..b81a17f49b --- /dev/null +++ b/adapters/synapseHX/params_test.go @@ -0,0 +1,45 @@ +package synapseHX + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch json-schemas. %v", err) + } + + for _, param := range validParams { + if err := validator.Validate(openrtb_ext.BidderSynapseHX, json.RawMessage(param)); err != nil { + t.Errorf("Schema rejected valid params: %s", param) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch json-schemas. %v", err) + } + + for _, param := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderSynapseHX, json.RawMessage(param)); err == nil { + t.Errorf("Schema allowed invalid params: %s", param) + } + } +} + +var validParams = []string{ + `{"tenantId":"a"}`, + `{"tenantId":"8cd85aed-25a6-4db0-ad98-4a3af1f7601c"}`, +} + +var invalidParams = []string{ + `{}`, + `{"tenantId":1}`, + `{"tenantId":""}`, +} diff --git a/adapters/synapseHX/synapseHX.go b/adapters/synapseHX/synapseHX.go new file mode 100644 index 0000000000..2181305687 --- /dev/null +++ b/adapters/synapseHX/synapseHX.go @@ -0,0 +1,147 @@ +package synapseHX + +import ( + "fmt" + "net/http" + "net/url" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + + return bidder, nil +} + +func (adapter *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var requests []*adapters.RequestData + + var tenantId string + + if len(request.Imp) == 0 { + return nil, []error{fmt.Errorf("request contains no impressions")} + } + + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { + return nil, []error{fmt.Errorf("failed to unmarshal bidder ext: %w", err)} + } + + var ext openrtb_ext.ExtImpSynapseHX + if err := jsonutil.Unmarshal(bidderExt.Bidder, &ext); err != nil { + return nil, []error{fmt.Errorf("failed to unmarshal bidder parameters: %w", err)} + } + + tenantId = ext.TenantID + + requestBody, err := jsonutil.Marshal(request) + if err != nil { + return nil, []error{fmt.Errorf("failed to marshal request: %w", err)} + } + + url, _ := url.Parse(adapter.endpoint) + q := url.Query() + q.Set("pid", tenantId) + url.RawQuery = q.Encode() + + requestData := &adapters.RequestData{ + Method: http.MethodPost, + Uri: url.String(), + Body: requestBody, + Headers: buildRequestHeaders(), + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + } + + requests = append(requests, requestData) + + return requests, nil +} + +func (adapter *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 bidResponse openrtb2.BidResponse + if err := jsonutil.Unmarshal(response.Body, &bidResponse); err != nil { + return nil, []error{&errortypes.BadInput{Message: fmt.Sprintf("failed to unmarshal response body: %v", err)}} + } + + if len(bidResponse.SeatBid) == 0 || len(bidResponse.SeatBid[0].Bid) == 0 { + return nil, nil + } + + var errs []error + bidderResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResponse.SeatBid[0].Bid)) + + for i := range bidResponse.SeatBid { + for j := range bidResponse.SeatBid[i].Bid { + bid := &bidResponse.SeatBid[i].Bid[j] + bidType, err := getMediaTypeForBid(bid) + + if err != nil { + errs = append(errs, err) + } else { + bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{ + Bid: bid, + BidType: bidType, + }) + } + } + } + + return bidderResponse, errs +} + +func buildRequestHeaders() 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.6") + + return headers +} + +func getMediaTypeForBid(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { + if bid.MType != 0 { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + default: + return "", fmt.Errorf("unsupported media type %d", bid.MType) + } + } + + if bid.Ext != nil { + var bidExt openrtb_ext.ExtBid + err := jsonutil.Unmarshal(bid.Ext, &bidExt) + if err == nil && bidExt.Prebid != nil { + switch bidExt.Prebid.Type { + case openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo: + return bidExt.Prebid.Type, nil + default: + return "", fmt.Errorf("unsupported media type \"%s\"", bidExt.Prebid.Type) + } + } + } + + return "", fmt.Errorf("failed to parse impression \"%s\" mediatype", bid.ImpID) +} diff --git a/adapters/synapseHX/synapseHX_test.go b/adapters/synapseHX/synapseHX_test.go new file mode 100644 index 0000000000..21ea7af97c --- /dev/null +++ b/adapters/synapseHX/synapseHX_test.go @@ -0,0 +1,18 @@ +package synapseHX + +import ( + "testing" + + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderSynapseHX, config.Adapter{ + Endpoint: "http://localhost:8080/bidder/"}, config.Server{}) + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + adapterstest.RunJSONBidderTest(t, "synapseHXtest", bidder) +} diff --git a/adapters/synapseHX/synapseHXtest/exemplary/banner.json b/adapters/synapseHX/synapseHXtest/exemplary/banner.json new file mode 100644 index 0000000000..586a35dbaf --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/exemplary/banner.json @@ -0,0 +1,167 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "http://localhost:8080/bidder/?pid=a", + "body": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "body": { + "id": "bid-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid-item-id", + "impid": "imp-id", + "price": 0.04, + "adm": "Ad", + "adomain": [ + "example.com" + ], + "mtype": 1 + } + ], + "seat": "seat-1" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "bid-resp-id", + "bids": [ + { + "bid": { + "id": "bid-item-id", + "impid": "imp-id", + "price": 0.04, + "adm": "Ad", + "adomain": [ + "example.com" + ], + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/synapseHX/synapseHXtest/exemplary/video.json b/adapters/synapseHX/synapseHXtest/exemplary/video.json new file mode 100644 index 0000000000..bb4216b7c4 --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/exemplary/video.json @@ -0,0 +1,253 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a" + } + }, + "instl": 1, + "bidfloor": 0.2, + "bidfloorcur": "USD", + "video": { + "api": [ + 7 + ], + "battr": [ + 16 + ], + "companiontype": [ + 1, + 2 + ], + "h": 480, + "w": 320, + "skip": 1, + "mimes": [ + "video/mp4" + ], + "minduration": 5, + "maxduration": 30, + "linearity": 1, + "protocols": [ + 2, + 3, + 5, + 6 + ], + "pos": 7, + "startdelay": 0, + "placement": 4, + "skipmin": 0, + "skipafter": 0, + "companionad": [ + { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif" + ], + "api": [ + 3, + 5, + 6 + ], + "vcm": 1 + } + ], + "delivery": [], + "maxextended": 0 + }, + "metric": [ + { + "type": "viewability", + "value": 0.97, + "vendor": "ZZZ" + } + ], + "displaymanager": "ZZZ", + "displaymanagerver": "42.42.42", + "secure": 1 + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "http://localhost:8080/bidder/?pid=a", + "body": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a" + } + }, + "instl": 1, + "bidfloor": 0.2, + "bidfloorcur": "USD", + "video": { + "api": [ + 7 + ], + "battr": [ + 16 + ], + "companiontype": [ + 1, + 2 + ], + "h": 480, + "w": 320, + "skip": 1, + "mimes": [ + "video/mp4" + ], + "minduration": 5, + "maxduration": 30, + "linearity": 1, + "protocols": [ + 2, + 3, + 5, + 6 + ], + "pos": 7, + "startdelay": 0, + "placement": 4, + "companionad": [ + { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif" + ], + "api": [ + 3, + 5, + 6 + ], + "vcm": 1 + } + ] + }, + "metric": [ + { + "type": "viewability", + "value": 0.97, + "vendor": "ZZZ" + } + ], + "displaymanager": "ZZZ", + "displaymanagerver": "42.42.42", + "secure": 1 + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "body": { + "id": "bid-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid-item-id", + "impid": "imp-id", + "price": 0.03, + "adm": "PrebidSample Video Ad00:00:30https://advertiser.com/video.mp4", + "adomain": [ + "example.com" + ], + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "seat-1" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "bid-resp-id", + "bids": [ + { + "bid": { + "id": "bid-item-id", + "impid": "imp-id", + "price": 0.03, + "adm": "PrebidSample Video Ad00:00:30https://advertiser.com/video.mp4", + "adomain": [ + "example.com" + ], + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-empty-seatbid.json b/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-empty-seatbid.json new file mode 100644 index 0000000000..e1a55566b1 --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-empty-seatbid.json @@ -0,0 +1,137 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "http://localhost:8080/bidder/?pid=a", + "body": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "body": { + "id": "bid-resp-id", + "seatbid": [ + { + "bid": [] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [] +} diff --git a/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-media-type.json b/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-media-type.json new file mode 100644 index 0000000000..07050f4159 --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-media-type.json @@ -0,0 +1,158 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "http://localhost:8080/bidder/?pid=a", + "body": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "body": { + "id": "bid-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid-item-id", + "impid": "imp-id", + "price": 0.04, + "adm": "Ad", + "adomain": [ + "example.com" + ], + "ext": { + "prebid": { + "type": "audio" + } + } + } + ], + "seat": "seat-1" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [{}], + "expectedMakeBidsErrors": [ + { + "value": "unsupported media type", + "comparison": "startswith" + } + ] +} diff --git a/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-mtype.json b/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-mtype.json new file mode 100644 index 0000000000..e9c9014e77 --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-mtype.json @@ -0,0 +1,154 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "http://localhost:8080/bidder/?pid=a", + "body": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "body": { + "id": "bid-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid-item-id", + "impid": "imp-id", + "price": 0.04, + "adm": "Ad", + "adomain": [ + "example.com" + ], + "mtype": 3 + } + ], + "seat": "seat-1" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [{}], + "expectedMakeBidsErrors": [ + { + "value": "unsupported media type", + "comparison": "startswith" + } + ] +} diff --git a/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-no-media-type.json b/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-no-media-type.json new file mode 100644 index 0000000000..4735ccd2a7 --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/supplemental/invalid-resp-no-media-type.json @@ -0,0 +1,153 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "http://localhost:8080/bidder/?pid=a", + "body": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "body": { + "id": "bid-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "bid-item-id", + "impid": "imp-id", + "price": 0.04, + "adm": "Ad", + "adomain": [ + "example.com" + ] + } + ], + "seat": "seat-1" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [{}], + "expectedMakeBidsErrors": [ + { + "value": "failed to parse impression", + "comparison": "startswith" + } + ] +} diff --git a/adapters/synapseHX/synapseHXtest/supplemental/request-invalid-imp-bidder-ext.json b/adapters/synapseHX/synapseHXtest/supplemental/request-invalid-imp-bidder-ext.json new file mode 100644 index 0000000000..382433ef83 --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/supplemental/request-invalid-imp-bidder-ext.json @@ -0,0 +1,55 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": 0 + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [], + "expectedBidResponses": [], + "expectedMakeRequestsErrors": [ + { + "value": "failed to unmarshal bidder parameters", + "comparison": "startswith" + } + ] +} diff --git a/adapters/synapseHX/synapseHXtest/supplemental/request-no-imp-ext.json b/adapters/synapseHX/synapseHXtest/supplemental/request-no-imp-ext.json new file mode 100644 index 0000000000..dec8f4a250 --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/supplemental/request-no-imp-ext.json @@ -0,0 +1,50 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [], + "expectedBidResponses": [], + "expectedMakeRequestsErrors": [ + { + "value": "failed to unmarshal bidder ext", + "comparison": "startswith" + } + ] +} diff --git a/adapters/synapseHX/synapseHXtest/supplemental/request-no-imp.json b/adapters/synapseHX/synapseHXtest/supplemental/request-no-imp.json new file mode 100644 index 0000000000..0217586de9 --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/supplemental/request-no-imp.json @@ -0,0 +1,24 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [], + "expectedBidResponses": [], + "expectedMakeRequestsErrors": [ + { + "value": "request contains no impressions", + "comparison": "literal" + } + ] +} diff --git a/adapters/synapseHX/synapseHXtest/supplemental/resp-invalid-no-body.json b/adapters/synapseHX/synapseHXtest/supplemental/resp-invalid-no-body.json new file mode 100644 index 0000000000..5c06b5add0 --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/supplemental/resp-invalid-no-body.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "http://localhost:8080/bidder/?pid=a", + "body": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.5" + ] + } + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "failed to unmarshal response body", + "comparison": "startswith" + } + ] +} diff --git a/adapters/synapseHX/synapseHXtest/supplemental/status-204.json b/adapters/synapseHX/synapseHXtest/supplemental/status-204.json new file mode 100644 index 0000000000..2e2e89bcef --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/supplemental/status-204.json @@ -0,0 +1,127 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "http://localhost:8080/bidder/?pid=a", + "body": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 204, + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ] + } + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/synapseHX/synapseHXtest/supplemental/status-400.json b/adapters/synapseHX/synapseHXtest/supplemental/status-400.json new file mode 100644 index 0000000000..85ba451867 --- /dev/null +++ b/adapters/synapseHX/synapseHXtest/supplemental/status-400.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "http://localhost:8080/bidder/?pid=a", + "body": { + "id": "auction-req-id", + "imp": [ + { + "id": "imp-id", + "ext": { + "bidder": { + "tenantId": "a", + "adUnitId": "b" + } + }, + "banner": { + "w": 320, + "h": 480, + "pos": 7, + "mimes": [ + "image/jpg", + "image/gif", + "text/html" + ], + "format": [ + { + "w": 320, + "h": 480 + } + ], + "api": [ + 5, + 7 + ], + "vcm": 1, + "id": "1" + } + } + ], + "site": { + "page": "https://example.com", + "publisher": { + "id": "publisher-id" + }, + "id": "site-id" + }, + "device": { + "ua": "Mozilla/5.0" + } + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 400, + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ] + } + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "startswith" + } + ] +} diff --git a/adapters/taboola/params_test.go b/adapters/taboola/params_test.go index 8018c4b9d9..bd1ccddbb0 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/taboola/taboola.go b/adapters/taboola/taboola.go index a11fbf6ce7..65b757bf3b 100644 --- a/adapters/taboola/taboola.go +++ b/adapters/taboola/taboola.go @@ -11,12 +11,12 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { @@ -239,7 +239,7 @@ func createTaboolaRequests(request *openrtb2.BidRequest) (taboolaRequests []*ope } if taboolaExt.PageType != "" { - requestExt, requestExtErr := makeRequestExt(taboolaExt.PageType) + requestExt, requestExtErr := makeRequestExt(taboolaExt.PageType, modifiedRequest.Ext) if requestExtErr == nil { modifiedRequest.Ext = requestExt } else { @@ -253,17 +253,25 @@ func createTaboolaRequests(request *openrtb2.BidRequest) (taboolaRequests []*ope return taboolaRequests, errs } -func makeRequestExt(pageType string) (json.RawMessage, error) { - requestExt := &RequestExt{ - PageType: pageType, +func makeRequestExt(pageType string, existingExt json.RawMessage) (json.RawMessage, error) { + extMap := make(map[string]json.RawMessage) + if len(existingExt) > 0 { + if err := jsonutil.Unmarshal(existingExt, &extMap); err != nil { + return nil, fmt.Errorf("could not unmarshal request ext: %s", err) + } } - requestExtJson, err := json.Marshal(requestExt) + pageTypeJson, err := jsonutil.Marshal(pageType) if err != nil { - return nil, fmt.Errorf("could not marshal %s, err: %s", requestExt, err) + return nil, fmt.Errorf("could not marshal pageType: %s", err) } - return requestExtJson, nil + extMap["pageType"] = pageTypeJson + requestExtJson, err := jsonutil.Marshal(extMap) + if err != nil { + return nil, fmt.Errorf("could not marshal request ext: %s", err) + } + return requestExtJson, nil } func getMediaType(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { @@ -303,5 +311,6 @@ func resolveMacros(bid *openrtb2.Bid) { 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) + bid.BURL = strings.Replace(bid.BURL, "${AUCTION_PRICE}", price, -1) } } diff --git a/adapters/taboola/taboola_test.go b/adapters/taboola/taboola_test.go index 082e480943..6a5a6ff316 100644 --- a/adapters/taboola/taboola_test.go +++ b/adapters/taboola/taboola_test.go @@ -1,11 +1,12 @@ package taboola import ( + "encoding/json" "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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -20,6 +21,34 @@ func TestJsonSamples(t *testing.T) { adapterstest.RunJSONBidderTest(t, "taboolatest", bidder) } +func TestMakeRequestExt(t *testing.T) { + t.Run("merges pageType into existing ext without dropping other fields", func(t *testing.T) { + existingExt := json.RawMessage(`{"prebid":{"integration":"pbjs"}}`) + + result, err := makeRequestExt("article", existingExt) + + assert.NoError(t, err) + assert.JSONEq(t, `{"prebid":{"integration":"pbjs"},"pageType":"article"}`, string(result)) + }) + + t.Run("sets pageType when existing ext is empty", func(t *testing.T) { + result, err := makeRequestExt("article", nil) + + assert.NoError(t, err) + assert.JSONEq(t, `{"pageType":"article"}`, string(result)) + }) + + t.Run("returns error when existing ext is invalid JSON", func(t *testing.T) { + invalidExt := json.RawMessage(`not-a-json-object`) + + result, err := makeRequestExt("article", invalidExt) + + assert.Error(t, err) + assert.Contains(t, err.Error(), "could not unmarshal request ext") + assert.Nil(t, result) + }) +} + func TestEmptyExternalUrl(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderTaboola, config.Adapter{ Endpoint: "http://whatever.com"}, config.Server{}) diff --git a/adapters/taboola/taboolatest/exemplary/bannerResolveMacro.json b/adapters/taboola/taboolatest/exemplary/bannerResolveMacro.json index b673096c0b..f2bf2574c6 100644 --- a/adapters/taboola/taboolatest/exemplary/bannerResolveMacro.json +++ b/adapters/taboola/taboolatest/exemplary/bannerResolveMacro.json @@ -114,7 +114,8 @@ "w": 300, "h": 250, "exp": 60, - "lurl": "https://lurl.domain.com/" + "lurl": "https://lurl.domain.com/", + "burl": "https://burl.domain.com/?wp=${AUCTION_PRICE}" } ], "seat": "1111" @@ -145,7 +146,8 @@ "w": 300, "h": 250, "exp": 60, - "lurl": "https://lurl.domain.com/" + "lurl": "https://lurl.domain.com/", + "burl": "https://burl.domain.com/?wp=2.1" }, "type": "banner" } diff --git a/adapters/taboola/taboolatest/exemplary/nativeResolveMacro.json b/adapters/taboola/taboolatest/exemplary/nativeResolveMacro.json index e30f123cc1..3a25b5688e 100644 --- a/adapters/taboola/taboolatest/exemplary/nativeResolveMacro.json +++ b/adapters/taboola/taboolatest/exemplary/nativeResolveMacro.json @@ -86,7 +86,8 @@ "cid": "cid", "crid": "crid", "lurl": "https://lurl.domain.com/", - "nurl": "nurl.com&wp=${AUCTION_PRICE}" + "nurl": "nurl.com&wp=${AUCTION_PRICE}", + "burl": "https://burl.domain.com/?wp=${AUCTION_PRICE}" } ], "seat": "1111" @@ -116,7 +117,8 @@ "cid": "cid", "crid": "crid", "lurl": "https://lurl.domain.com/", - "nurl": "nurl.com&wp=2.1" + "nurl": "nurl.com&wp=2.1", + "burl": "https://burl.domain.com/?wp=2.1" }, "type": "native" } diff --git a/adapters/taboola/taboolatest/exemplary/withPageTypeAndPrebidExt.json b/adapters/taboola/taboolatest/exemplary/withPageTypeAndPrebidExt.json new file mode 100644 index 0000000000..4c4856e047 --- /dev/null +++ b/adapters/taboola/taboolatest/exemplary/withPageTypeAndPrebidExt.json @@ -0,0 +1,176 @@ +{ + "mockBidRequest": { + "id": "request-id", + "imp": [ + { + "id": "impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "publisherId": "publisher-id", + "tagid": "tag-id", + "pageType": "article" + } + } + } + ], + "site": { + "domain": "http://domain.com", + "page": "http://page-domain.com" + }, + "device": { + "ua": "Mozilla/5.0", + "h": 300, + "w": 300 + }, + "ext": { + "prebid": { + "channel": { + "name": "web", + "version": "1.0" + }, + "integration": "pbjs", + "server": { + "externalurl": "https://pbs.example.com", + "gvlid": 42, + "datacenter": "us-east-1" + }, + "sdk": { + "renderers": [ + { + "name": "test-renderer", + "version": "1.0.0" + } + ] + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://display.whatever.com/12/publisher-id", + "body": { + "id": "request-id", + "imp": [ + { + "id": "impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "tag-id", + "ext": { + "bidder": { + "publisherId": "publisher-id", + "tagid": "tag-id", + "pageType": "article" + } + } + } + ], + "site": { + "id": "publisher-id", + "name": "publisher-id", + "domain": "http://domain.com", + "page": "http://page-domain.com", + "publisher": { + "id": "publisher-id" + } + }, + "device": { + "ua": "Mozilla/5.0", + "h": 300, + "w": 300 + }, + "ext": { + "pageType": "article", + "prebid": { + "channel": { + "name": "web", + "version": "1.0" + }, + "integration": "pbjs", + "server": { + "externalurl": "https://pbs.example.com", + "gvlid": 42, + "datacenter": "us-east-1" + }, + "sdk": { + "renderers": [ + { + "name": "test-renderer", + "version": "1.0.0" + } + ] + } + } + } + }, + "impIDs": ["impression-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "123", + "seatbid": [ + { + "bid": [ + { + "id": "request-id", + "impid": "impression-id", + "price": 2.1, + "adid": "1", + "adm": "", + "adomain": ["adomain.com"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "exp": 60 + } + ], + "seat": "1111" + } + ], + "bidid": "123", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "request-id", + "impid": "impression-id", + "price": 2.1, + "adid": "1", + "adm": "", + "adomain": ["adomain.com"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "exp": 60 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/taboola/utils.go b/adapters/taboola/utils.go deleted file mode 100644 index 2703ec69ad..0000000000 --- a/adapters/taboola/utils.go +++ /dev/null @@ -1,5 +0,0 @@ -package taboola - -type RequestExt struct { - PageType string `json:"pageType,omitempty"` -} diff --git a/adapters/tadvertising_blis/params_test.go b/adapters/tadvertising_blis/params_test.go new file mode 100644 index 0000000000..6e3d5ad138 --- /dev/null +++ b/adapters/tadvertising_blis/params_test.go @@ -0,0 +1,66 @@ +package tadvertising_blis + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type testSpec struct { + name string + json string + wantErr bool +} + +func testParams(t *testing.T, specs []testSpec) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + require.NoError(t, err, "Failed to fetch the json schema") + + for _, spec := range specs { + t.Run(spec.name, func(t *testing.T) { + err := validator.Validate(openrtb_ext.BidderTAdvertisingBlis, json.RawMessage(spec.json)) + if spec.wantErr { + assert.Error(t, err, "Expected error but got none for: %s", spec.json) + } else { + assert.NoError(t, err, "Unexpected error for: %s", spec.json) + } + }) + } +} + +func TestValidParams(t *testing.T) { + testParams(t, []testSpec{ + { + name: "Valid params with publisherId", + json: `{"publisherId": "1427ab10f2e448057ed3b422"}`, + }, + }) +} + +func TestInvalidParams(t *testing.T) { + testParams(t, []testSpec{ + { + name: "Empty params", + json: `{}`, + wantErr: true, + }, + { + name: "Empty publisherId", + json: `{"publisherId": ""}`, + wantErr: true, + }, + { + name: "Invalid publisherId type", + json: `{"publisherId": 123}`, + wantErr: true, + }, + { + name: "Too long publisherId", + json: `{"publisherId": "111111111111111111111111111111111"}`, + wantErr: true, + }, + }) +} diff --git a/adapters/tadvertising_blis/tadvertising_blis.go b/adapters/tadvertising_blis/tadvertising_blis.go new file mode 100644 index 0000000000..982f73d2e3 --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blis.go @@ -0,0 +1,151 @@ +package tadvertising_blis + +import ( + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/iterutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{} + bidder.endpoint = config.Endpoint + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var impExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(request.Imp[0].Ext, &impExt); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Invalid imp.ext for impression index %d. Error Information: %v", 0, err), + }} + } + var impExtBidder openrtb_ext.ImpExtTadvertising + if err := jsonutil.Unmarshal(impExt.Bidder, &impExtBidder); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Invalid imp.ext.bidder for impression index %d. Error Information: %v", 0, err), + }} + } + + if request.Site != nil && request.App == nil { + siteCopy := *request.Site + request.Site = &siteCopy + + if request.Site.Publisher != nil { + sitePublisherCopy := *request.Site.Publisher + request.Site.Publisher = &sitePublisherCopy + request.Site.Publisher.ID = impExtBidder.PublisherId + } else { + request.Site.Publisher = &openrtb2.Publisher{} + request.Site.Publisher.ID = impExtBidder.PublisherId + } + } else if request.App != nil { + appCopy := *request.App + request.App = &appCopy + + if request.App.Publisher != nil { + appPublisherCopy := *request.App.Publisher + request.App.Publisher = &appPublisherCopy + request.App.Publisher.ID = impExtBidder.PublisherId + } else { + request.App.Publisher = &openrtb2.Publisher{} + request.App.Publisher.ID = impExtBidder.PublisherId + } + } else { + request.Site = &openrtb2.Site{} + request.Site.Publisher = &openrtb2.Publisher{} + request.Site.Publisher.ID = impExtBidder.PublisherId + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json") + headers.Add("X-Supply-Partner-Id", impExtBidder.PublisherId) + + requestJSON, err := jsonutil.Marshal(request) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: http.MethodPost, + Uri: a.endpoint, + Headers: headers, + Body: requestJSON, + 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(request.Imp)) + if response.Cur != "" { + bidResponse.Currency = response.Cur + } + + var errors []error + for seatBid := range iterutil.SlicePointerValues(response.SeatBid) { + for bid := range iterutil.SlicePointerValues(seatBid.Bid) { + resolveMacros(bid) + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errors = append(errors, err) + continue + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: bid, + BidType: bidType, + }) + } + } + return bidResponse, 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 + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Failed to parse media type of impression ID \"%s\"", bid.ImpID), + } + } +} + +func resolveMacros(bid *openrtb2.Bid) { + if bid != nil { + price := strconv.FormatFloat(bid.Price, 'f', -1, 64) + bid.NURL = strings.ReplaceAll(bid.NURL, "${AUCTION_PRICE}", price) + bid.AdM = strings.ReplaceAll(bid.AdM, "${AUCTION_PRICE}", price) + bid.BURL = strings.ReplaceAll(bid.BURL, "${AUCTION_PRICE}", price) + } +} diff --git a/adapters/tadvertising_blis/tadvertising_blis_test.go b/adapters/tadvertising_blis/tadvertising_blis_test.go new file mode 100644 index 0000000000..a68a35bfc1 --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blis_test.go @@ -0,0 +1,20 @@ +package tadvertising_blis + +import ( + "testing" + + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/require" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderTAdvertisingBlis, config.Adapter{ + Endpoint: "https://example.endpoint/"}, + config.Server{ExternalUrl: "http://example.server", GvlID: 1, DataCenter: "2"}) + + require.NoError(t, buildErr) + + adapterstest.RunJSONBidderTest(t, "tadvertising_blistest", bidder) +} diff --git a/adapters/tadvertising_blis/tadvertising_blistest/exemplary/banner.json b/adapters/tadvertising_blis/tadvertising_blistest/exemplary/banner.json new file mode 100644 index 0000000000..78b8ccb3ee --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/exemplary/banner.json @@ -0,0 +1,229 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "ext": { + "bidder": { + "publisherId": "123" + } + }, + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0, + "api": [ + ] + }, + "tagid": "test-tag-id", + "bidfloor": 0, + "secure": 1 + } + ], + "site": { + "publisher": { + "id": "123" + } + }, + "device": { + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "deviceType": 2, + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "pid": "test-pid", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "coppa": 0, + "gdpr": 0 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "headers": { + "Content-Type": ["application/json"], + "X-Supply-Partner-Id": ["123"] + }, + "impIDs": [ + "test-impression-id" + ], + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "tagid": "test-tag-id", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "123" + } + } + } + ], + "site": { + "publisher": { + "id": "123" + } + }, + "device": { + "devicetype": 2, + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "gdpr": 0 + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "10b1e33f-fddc-4621-a472-d7bff0529cbf", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "1", + "price": 0.78740156, + "protocol": 0, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "attr": [], + "api": 0, + "mtype": 1, + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + } + ], + "seat": "2271" + } + ], + "cur": "USD", + "ext": { + "uss": 1 + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "1", + "price": 0.78740156, + "mtype": 1, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/exemplary/native.json b/adapters/tadvertising_blis/tadvertising_blistest/exemplary/native.json new file mode 100644 index 0000000000..6166d024a9 --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/exemplary/native.json @@ -0,0 +1,131 @@ +{ + "mockBidRequest": { + "id": "123456789", + "imp": [ + { + "id": "testimp", + "native": { + "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":90}},{\"id\":2,\"img\":{\"type\":3,\"wmin\":100,\"hmin\":100}},{\"id\":3,\"data\":{\"type\":2}}]}", + "ver": "1.2" + }, + "bidfloor": 0.98, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "publisherId": "123" + } + } + } + ], + "cur": ["USD"], + "site": { + "publisher": { + "domain": "example.com" + }, + "page": "http://lh.example.com/prebid_server_kitchen_sink.html?pbjs_debug=true", + "cat": ["site-cat"] + }, + "device": { + "w": 1434, + "h": 686, + "geo": { + "country": "USA" + }, + "ip": "8.8.8.8" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "headers": { + "Content-Type": ["application/json"], + "X-Supply-Partner-Id": ["123"] + }, + "impIDs": ["testimp"], + "body": { + "id": "123456789", + "imp": [ + { + "id": "testimp", + "native": { + "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":90}},{\"id\":2,\"img\":{\"type\":3,\"wmin\":100,\"hmin\":100}},{\"id\":3,\"data\":{\"type\":2}}]}", + "ver": "1.2" + }, + "bidfloor": 0.98, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "publisherId": "123" + } + } + } + ], + "site": { + "cat": ["site-cat"], + "page": "http://lh.example.com/prebid_server_kitchen_sink.html?pbjs_debug=true", + "publisher": { + "domain": "example.com", + "id": "123" + } + }, + "device": { + "geo": { + "country": "USA" + }, + "ip": "8.8.8.8", + "h": 686, + "w": 1434 + }, + "cur": ["USD"] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "123456789", + "seatbid": [ + { + "seat": "None", + "bid": [ + { + "id": "1", + "impid": "testimp", + "price": 1.3, + "crid": "9999999", + "adomain": ["example.com"], + "cid": "999999", + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Native Ad Title\"}},{\"id\":2,\"img\":{\"url\":\"https://adserverexample.com/image.jpg\",\"w\":1200,\"h\":627}},{\"id\":3,\"data\":{\"value\":\"Sponsored\"}}],\"link\":{\"url\":\"https://clickexample.com\"},\"imptrackers\":[\"https://trackingexample.com/pixel?wp=${AUCTION_PRICE}\"]}}", + "cat": ["IAB3-1"], + "burl": "https://trackingexample.com/pixel?wp=${AUCTION_PRICE}", + "mtype": 4 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "1", + "impid": "testimp", + "price": 1.3, + "crid": "9999999", + "adomain": ["example.com"], + "cid": "999999", + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Native Ad Title\"}},{\"id\":2,\"img\":{\"url\":\"https://adserverexample.com/image.jpg\",\"w\":1200,\"h\":627}},{\"id\":3,\"data\":{\"value\":\"Sponsored\"}}],\"link\":{\"url\":\"https://clickexample.com\"},\"imptrackers\":[\"https://trackingexample.com/pixel?wp=1.3\"]}}", + "cat": ["IAB3-1"], + "burl": "https://trackingexample.com/pixel?wp=1.3", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/exemplary/video.json b/adapters/tadvertising_blis/tadvertising_blistest/exemplary/video.json new file mode 100644 index 0000000000..352111a98e --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/exemplary/video.json @@ -0,0 +1,153 @@ +{ + "mockBidRequest": { + "id": "123456789", + "imp": [ + { + "ext": { + "bidder": { + "publisherId": "123" + } + }, + "id": "testimp", + "video": { + "mimes": ["video/mp4"], + "minduration": 5, + "maxduration": 30, + "protocols": [2, 3, 5, 6], + "w": 640, + "h": 480 + }, + "bidfloor": 0.98, + "bidfloorcur": "USD" + } + ], + "cur": [ + "USD" + ], + "site": { + "publisher": { + "domain": "example.com" + }, + "page": "http://lh.example.com/prebid_server_kitchen_sink.html?pbjs_debug=true", + "cat": [ + "site-cat" + ] + }, + "device": { + "w": 1434, + "h": 686, + "geo": { + "country": "USA" + }, + "ip": "8.8.8.8" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "headers": { + "Content-Type": ["application/json"], + "X-Supply-Partner-Id": ["123"] + }, + "impIDs": [ + "testimp" + ], + "body": { + "id": "123456789", + "imp": [ + { + "id": "testimp", + "video": { + "mimes": ["video/mp4"], + "minduration": 5, + "maxduration": 30, + "protocols": [2, 3, 5, 6], + "w": 640, + "h": 480 + }, + "bidfloor": 0.98, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "publisherId": "123" + } + } + } + ], + "site": { + "cat": [ + "site-cat" + ], + "page": "http://lh.example.com/prebid_server_kitchen_sink.html?pbjs_debug=true", + "publisher": { + "id": "123", + "domain": "example.com" + } + }, + "device": { + "geo": { + "country": "USA" + }, + "ip": "8.8.8.8", + "h": 686, + "w": 1434 + }, + "cur": [ + "USD" + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "123456789", + "seatbid": [ + { + "seat": "None", + "bid": [ + { + "id": "1", + "impid": "testimp", + "price": 1.5, + "crid": "9999999", + "w": 640, + "h": 480, + "adomain": ["example.com"], + "cid": "999999", + "adm": "blistracker", + "cat": ["IAB3-1"], + "burl": "https://trackingexample.com/pixel?wp=${AUCTION_PRICE}", + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "1", + "impid": "testimp", + "price": 1.5, + "crid": "9999999", + "w": 640, + "h": 480, + "adomain": ["example.com"], + "cid": "999999", + "adm": "blistracker", + "cat": ["IAB3-1"], + "burl": "https://trackingexample.com/pixel?wp=1.5", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher.json new file mode 100644 index 0000000000..427a68da63 --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher.json @@ -0,0 +1,226 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "ext": { + "bidder": { + "publisherId": "123" + } + }, + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0, + "api": [ + ] + }, + "tagid": "test-tag-id", + "bidfloor": 0, + "secure": 1 + } + ], + "site": { + }, + "device": { + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "deviceType": 2, + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "pid": "test-pid", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "coppa": 0, + "gdpr": 0 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "headers": { + "Content-Type": ["application/json"], + "X-Supply-Partner-Id": ["123"] + }, + "impIDs": [ + "test-impression-id" + ], + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "tagid": "test-tag-id", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "123" + } + } + } + ], + "site": { + "publisher": { + "id": "123" + } + }, + "device": { + "devicetype": 2, + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "gdpr": 0 + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "10b1e33f-fddc-4621-a472-d7bff0529cbf", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "1", + "price": 0.78740156, + "protocol": 0, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "attr": [], + "api": 0, + "mtype": 1, + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + } + ], + "seat": "2271" + } + ], + "cur": "USD", + "ext": { + "uss": 1 + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "1", + "price": 0.78740156, + "mtype": 1, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher_id.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher_id.json new file mode 100644 index 0000000000..06b0079923 --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher_id.json @@ -0,0 +1,228 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "ext": { + "bidder": { + "publisherId": "123" + } + }, + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0, + "api": [ + ] + }, + "tagid": "test-tag-id", + "bidfloor": 0, + "secure": 1 + } + ], + "site": { + "publisher": { + } + }, + "device": { + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "deviceType": 2, + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "pid": "test-pid", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "coppa": 0, + "gdpr": 0 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "headers": { + "Content-Type": ["application/json"], + "X-Supply-Partner-Id": ["123"] + }, + "impIDs": [ + "test-impression-id" + ], + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "tagid": "test-tag-id", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "123" + } + } + } + ], + "site": { + "publisher": { + "id": "123" + } + }, + "device": { + "devicetype": 2, + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "gdpr": 0 + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "10b1e33f-fddc-4621-a472-d7bff0529cbf", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "1", + "price": 0.78740156, + "protocol": 0, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "attr": [], + "api": 0, + "mtype": 1, + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + } + ], + "seat": "2271" + } + ], + "cur": "USD", + "ext": { + "uss": 1 + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "1", + "price": 0.78740156, + "mtype": 1, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher_id_in_app.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher_id_in_app.json new file mode 100644 index 0000000000..5d490352a0 --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher_id_in_app.json @@ -0,0 +1,228 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "ext": { + "bidder": { + "publisherId": "123" + } + }, + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0, + "api": [ + ] + }, + "tagid": "test-tag-id", + "bidfloor": 0, + "secure": 1 + } + ], + "app": { + "publisher": { + } + }, + "device": { + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "deviceType": 2, + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "pid": "test-pid", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "coppa": 0, + "gdpr": 0 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "headers": { + "Content-Type": ["application/json"], + "X-Supply-Partner-Id": ["123"] + }, + "impIDs": [ + "test-impression-id" + ], + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "tagid": "test-tag-id", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "123" + } + } + } + ], + "device": { + "devicetype": 2, + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "gdpr": 0 + }, + "app": { + "publisher": { + "id": "123" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "10b1e33f-fddc-4621-a472-d7bff0529cbf", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "1", + "price": 0.78740156, + "protocol": 0, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "attr": [], + "api": 0, + "mtype": 1, + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + } + ], + "seat": "2271" + } + ], + "cur": "USD", + "ext": { + "uss": 1 + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "1", + "price": 0.78740156, + "mtype": 1, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher_in_app.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher_in_app.json new file mode 100644 index 0000000000..bb88055867 --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_publisher_in_app.json @@ -0,0 +1,226 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "ext": { + "bidder": { + "publisherId": "123" + } + }, + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0, + "api": [ + ] + }, + "tagid": "test-tag-id", + "bidfloor": 0, + "secure": 1 + } + ], + "app": { + }, + "device": { + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "deviceType": 2, + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "pid": "test-pid", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "coppa": 0, + "gdpr": 0 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "headers": { + "Content-Type": ["application/json"], + "X-Supply-Partner-Id": ["123"] + }, + "impIDs": [ + "test-impression-id" + ], + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "tagid": "test-tag-id", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "123" + } + } + } + ], + "device": { + "devicetype": 2, + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "gdpr": 0 + }, + "app": { + "publisher": { + "id": "123" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "10b1e33f-fddc-4621-a472-d7bff0529cbf", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "1", + "price": 0.78740156, + "protocol": 0, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "attr": [], + "api": 0, + "mtype": 1, + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + } + ], + "seat": "2271" + } + ], + "cur": "USD", + "ext": { + "uss": 1 + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "1", + "price": 0.78740156, + "mtype": 1, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_site.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_site.json new file mode 100644 index 0000000000..f245874aa0 --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/banner_no_site.json @@ -0,0 +1,224 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "ext": { + "bidder": { + "publisherId": "123" + } + }, + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0, + "api": [ + ] + }, + "tagid": "test-tag-id", + "bidfloor": 0, + "secure": 1 + } + ], + "device": { + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "deviceType": 2, + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "pid": "test-pid", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "coppa": 0, + "gdpr": 0 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "headers": { + "Content-Type": ["application/json"], + "X-Supply-Partner-Id": ["123"] + }, + "impIDs": [ + "test-impression-id" + ], + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "tagid": "test-tag-id", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "123" + } + } + } + ], + "site": { + "publisher": { + "id": "123" + } + }, + "device": { + "devicetype": 2, + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "gdpr": 0 + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "10b1e33f-fddc-4621-a472-d7bff0529cbf", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "1", + "price": 0.78740156, + "protocol": 0, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "attr": [], + "api": 0, + "mtype": 1, + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + } + ], + "seat": "2271" + } + ], + "cur": "USD", + "ext": { + "uss": 1 + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "1", + "price": 0.78740156, + "mtype": 1, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/bid-macro-replace.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/bid-macro-replace.json new file mode 100644 index 0000000000..de11c040f3 --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/bid-macro-replace.json @@ -0,0 +1,233 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "ext": { + "bidder": { + "publisherId": "123" + } + }, + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0, + "api": [ + ] + }, + "tagid": "test-tag-id", + "bidfloor": 0, + "secure": 1 + } + ], + "site": { + "publisher": { + "id": "123" + } + }, + "device": { + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "deviceType": 2, + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "pid": "test-pid", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "coppa": 0, + "gdpr": 0 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "headers": { + "Content-Type": ["application/json"], + "X-Supply-Partner-Id": ["123"] + }, + "impIDs": [ + "test-impression-id" + ], + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "tagid": "test-tag-id", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "123" + } + } + } + ], + "site": { + "publisher": { + "id": "123" + } + }, + "device": { + "devicetype": 2, + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "gdpr": 0 + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "10b1e33f-fddc-4621-a472-d7bff0529cbf", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "1", + "price": 2.3, + "protocol": 0, + "adm": "

I am an ad and cost ${AUCTION_PRICE}

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "attr": [], + "api": 0, + "mtype": 1, + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ], + "nurl": "https://test.com/${AUCTION_PRICE}", + "burl": "https://test.com/${AUCTION_PRICE}" + } + ], + "seat": "2271" + } + ], + "cur": "USD", + "ext": { + "uss": 1 + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "1", + "price": 2.3, + "mtype": 1, + "adm": "

I am an ad and cost 2.3

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ], + "nurl": "https://test.com/2.3", + "burl": "https://test.com/2.3" + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/invalid-imp-ext-bidder.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/invalid-imp-ext-bidder.json new file mode 100644 index 0000000000..2d0e1a270c --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/invalid-imp-ext-bidder.json @@ -0,0 +1,18 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "ext": {} + } + ] + }, + + "expectedMakeRequestsErrors": [ + { + "value": "Invalid imp.ext.bidder for impression", + "comparison": "startswith" + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/invalid-imp-ext.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/invalid-imp-ext.json new file mode 100644 index 0000000000..31e261e6fa --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/invalid-imp-ext.json @@ -0,0 +1,17 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp" + } + ] + }, + + "expectedMakeRequestsErrors": [ + { + "value": "Invalid imp.ext for impression", + "comparison": "startswith" + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/multiImpressionsRequest.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/multiImpressionsRequest.json new file mode 100644 index 0000000000..4108487e0e --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/multiImpressionsRequest.json @@ -0,0 +1,305 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "ext": { + "bidder": { + "publisherId": "123" + } + }, + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0, + "api": [ + ] + }, + "tagid": "test-tag-id", + "bidfloor": 0, + "secure": 1 + }, + { + "ext": { + "bidder": { + "publisherId": "123" + } + }, + "id": "test-impression-id2", + "banner": { + "w": 300, + "h": 250, + "pos": 0, + "api": [ + ] + }, + "tagid": "test-tag-id2", + "bidfloor": 0, + "secure": 1 + } + ], + "site": { + "publisher": { + "id": "123" + } + }, + "device": { + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "deviceType": 2, + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "pid": "test-pid", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "coppa": 0, + "gdpr": 0 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "headers": { + "Content-Type": ["application/json"], + "X-Supply-Partner-Id": ["123"] + }, + "impIDs": [ + "test-impression-id", + "test-impression-id2" + ], + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-impression-id", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "tagid": "test-tag-id", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "123" + } + } + }, + { + "ext": { + "bidder": { + "publisherId": "123" + } + }, + "id": "test-impression-id2", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "tagid": "test-tag-id2", + "secure": 1 + } + ], + "site": { + "publisher": { + "id": "123" + } + }, + "device": { + "devicetype": 2, + "ua": "test-user-agent", + "geo": { + "country": "US" + }, + "dnt": 0, + "lmt": 0, + "ip": "127.0.0.1", + "make": "test-make", + "model": "test-model", + "os": "test-os", + "osv": "test-osv", + "h": 1080, + "w": 1920, + "language": "en", + "ifa": "test-ifa" + }, + "test": 1, + "at": 1, + "tmax": 100, + "source": { + "fd": 1, + "tid": "test-transaction-id", + "pchain": "test-pchain", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "test-asi", + "sid": "test-sid", + "rid": "test-rid", + "name": "test-name", + "domain": "test-domain", + "hp": 1, + "ext": "test-ext" + } + ], + "ver": "1.0", + "ext": "test-ext" + }, + "ext": "test-ext" + }, + "regs": { + "gdpr": 0 + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "10b1e33f-fddc-4621-a472-d7bff0529cbf", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "1", + "price": 0.78740156, + "protocol": 0, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "attr": [], + "api": 0, + "mtype": 1, + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + }, + { + "id": "1", + "impid": "2", + "price": 0.78740156, + "protocol": 0, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "attr": [], + "api": 0, + "mtype": 1, + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + } + ], + "seat": "2271" + } + ], + "cur": "USD", + "ext": { + "uss": 1 + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "1", + "price": 0.78740156, + "mtype": 1, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + }, + "type": "banner" + }, + { + "bid": { + "id": "1", + "impid": "2", + "price": 0.78740156, + "mtype": 1, + "adm": "

I am an ad

", + "adomain": [ + "emetriq.com" + ], + "cid": "ay35w7m", + "crid": "id8tke3f", + "w": 300, + "h": 250, + "cat": [ + "IAB2", + "IAB2-3" + ] + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/response-http-204.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/response-http-204.json new file mode 100644 index 0000000000..d75a72db37 --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/response-http-204.json @@ -0,0 +1,57 @@ +{ + "mockBidRequest": { + "id": "test-req", + "site": { + "page": "prebid.org" + }, + "imp": [{ + "id": "test-imp", + "banner": { + "format": [{ + "w": 300, + "h": 600 + }] + }, + "ext": { + "bidder": { + "publisherId": "123" + } + } + }] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "body": { + "id": "test-req", + "site": { + "page": "prebid.org", + "publisher": { + "id": "123" + } + }, + "imp": [{ + "id": "test-imp", + "banner": { + "format": [{ + "w": 300, + "h": 600 + }] + }, + "ext": { + "bidder": { + "publisherId": "123" + } + } + }] + }, + "impIDs":["test-imp"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/response-http-500.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/response-http-500.json new file mode 100644 index 0000000000..90f52ce01b --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/response-http-500.json @@ -0,0 +1,61 @@ +{ + "mockBidRequest": { + "id": "test-req", + "site": { + "page": "prebid.org" + }, + "imp": [{ + "id": "test-imp", + "banner": { + "format": [{ + "w": 300, + "h": 600 + }] + }, + "ext": { + "bidder": { + "publisherId": "123" + } + } + }] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "body": { + "id": "test-req", + "site": { + "page": "prebid.org", + "publisher": { + "id": "123" + } + }, + "imp": [{ + "id": "test-imp", + "banner": { + "format": [{ + "w": 300, + "h": 600 + }] + }, + "ext": { + "bidder": { + "publisherId": "123" + } + } + }] + }, + "impIDs":["test-imp"] + }, + "mockResponse": { + "status": 500, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [{ + "value": "Unexpected status code", + "comparison": "startswith" + }] +} \ No newline at end of file diff --git a/adapters/tadvertising_blis/tadvertising_blistest/supplemental/unsupported-media-type.json b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/unsupported-media-type.json new file mode 100644 index 0000000000..8751c015e4 --- /dev/null +++ b/adapters/tadvertising_blis/tadvertising_blistest/supplemental/unsupported-media-type.json @@ -0,0 +1,93 @@ +{ + "mockBidRequest": { + "id": "test-req", + "site": { + "page": "prebid.org" + }, + "imp": [{ + "id": "test-imp", + "banner": { + "format": [{ + "w": 300, + "h": 600 + }] + }, + "ext": { + "bidder": { + "publisherId": "123" + } + } + }] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.endpoint/", + "body": { + "id": "test-req", + "site": { + "page": "prebid.org", + "publisher": { + "id": "123" + } + }, + "imp": [{ + "id": "test-imp", + "banner": { + "format": [{ + "w": 300, + "h": 600 + }] + }, + "ext": { + "bidder": { + "publisherId": "123" + } + } + }] + }, + "impIDs":["test-imp"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-req", + "seatbid": [ + { + "seat": "None", + "bid": [ + { + "id": "1", + "impid": "testimp", + "price": 1.2, + "crid": "9999999", + "w": 320, + "h": 50, + "adomain": [ + "example.com" + ], + "cid": "999999", + "adm": "\"\"", + "burl": "https://trackingexample.com/pixel?wp=${AUCTION_PRICE}", + "mtype": 6 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + ] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Failed to parse media type of impression ID \"testimp\"", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/tappx/params_test.go b/adapters/tappx/params_test.go index 07b56bf80c..fd174f8309 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -35,7 +35,21 @@ func TestInvalidParams(t *testing.T) { var validParams = []string{ `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915"}`, - `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"test.tappx.com"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"host"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"host.example.com"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"host.example.com:8080"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"host-example.test"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"Host.Example.com"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"localhost:3000"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"/path"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"//evil.com"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"host/path"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"host?query=1"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"host#fragment"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"user@host"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"https://host.com"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"host:notaport"}`, + `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"host:8080:extra"}`, `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"test.tappx.com", "bidfloor":0.5}`, `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"test.tappx.com", "bidfloor":0.5, "mktag":"txmk-xxxxx-xxx-xxxx"}`, `{"tappxkey":"pub-12345-android-9876", "endpoint":"ZZ1INTERNALTEST149147915", "host":"test.tappx.com", "bidfloor":0.5, "bcid":["123"]}`, diff --git a/adapters/tappx/tappx.go b/adapters/tappx/tappx.go index 71bad1543b..51738aa09c 100644 --- a/adapters/tappx/tappx.go +++ b/adapters/tappx/tappx.go @@ -11,12 +11,13 @@ import ( "time" "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/urlutil" ) const TAPPX_BIDDER_VERSION = "1.6" @@ -118,7 +119,9 @@ func (a *TappxAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapt }}, []error{} } -// Builds enpoint url based on adapter-specific pub settings from imp.ext +// Builds endpoint url based on adapter-specific pub settings from imp.ext. +// NOTE: The deprecated "host" param (params.Host) is intentionally unused here. +// If it is ever reintroduced, it MUST be validated with urlutil.IsSafeHost to prevent SSRF. func (a *TappxAdapter) buildEndpointURL(params *openrtb_ext.ExtImpTappx, test int) (string, error) { if params.Endpoint == "" { @@ -132,7 +135,6 @@ func (a *TappxAdapter) buildEndpointURL(params *openrtb_ext.ExtImpTappx, test in Message: "Tappx key undefined", } } - isNewEndpoint, err := regexp.Match(`^(zz|vz)[0-9]{3,}([a-z]{2,3}|test)$`, []byte(params.Endpoint)) if err != nil { return "", &errortypes.BadInput{ @@ -141,8 +143,17 @@ func (a *TappxAdapter) buildEndpointURL(params *openrtb_ext.ExtImpTappx, test in } var tappxHost string if isNewEndpoint { + // Defense-in-depth: the runtime regex above is stricter than IsSafeHost, + // so this check is currently unreachable. It guards against future relaxation + // of the regex inadvertently allowing SSRF via subdomain injection. + if !urlutil.IsSafeHost(params.Endpoint) { + return "", &errortypes.BadInput{ + Message: "Invalid Tappx endpoint", + } + } tappxHost = params.Endpoint + ".pub.tappx.com/rtb/" } else { + // endpoint is used as a path segment on fixed domain: ssp.api.tappx.com/rtb/v2/{endpoint} tappxHost = "ssp.api.tappx.com/rtb/v2/" } diff --git a/adapters/tappx/tappx_test.go b/adapters/tappx/tappx_test.go index 3643a58cc4..2fc8b61665 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/adapters/targetVideo/params_test.go b/adapters/targetVideo/params_test.go new file mode 100644 index 0000000000..1839f0bbe6 --- /dev/null +++ b/adapters/targetVideo/params_test.go @@ -0,0 +1,45 @@ +package targetVideo + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + require.NoError(t, err, "Failed to fetch the json-schemas") + + for _, validParam := range validParams { + assert.NoError(t, validator.Validate(openrtb_ext.BidderTargetVideo, json.RawMessage(validParam)), + "Schema rejected targetVideo params: %s", validParam) + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + require.NoError(t, err, "Failed to fetch the json-schemas") + + for _, invalidParam := range invalidParams { + assert.Error(t, validator.Validate(openrtb_ext.BidderTargetVideo, json.RawMessage(invalidParam)), + "Schema should have rejected unexpected params: %s", invalidParam) + } +} + +var validParams = []string{ + `{"placementId":846}`, + `{"placementId":"846"}`, +} + +var invalidParams = []string{ + `null`, + `nil`, + `undefined`, + `{"placementId": "%9"}`, + `{"publisherId": "as9""}`, + `{"placementId": true}`, + `{"placementId": ""}`, +} diff --git a/adapters/targetVideo/targetvideo.go b/adapters/targetVideo/targetvideo.go new file mode 100644 index 0000000000..a9649f0ddb --- /dev/null +++ b/adapters/targetVideo/targetvideo.go @@ -0,0 +1,142 @@ +package targetVideo + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var errors []error + totalImps := len(request.Imp) + adapterRequests := make([]*adapters.RequestData, 0, totalImps) + + // Split multi-imp request into multiple ad server requests. SRA is currently not recommended. + for i := 0; i < totalImps; i++ { + adapterReq, err := a.makeRequest(*request, request.Imp[i]) + if err != nil { + errors = append(errors, err) + continue + } + adapterRequests = append(adapterRequests, adapterReq) + } + + return adapterRequests, errors +} + +func (a *adapter) makeRequest(request openrtb2.BidRequest, imp openrtb2.Imp) (*adapters.RequestData, error) { + + // For now, this adapter sends one imp per request, but we still + // iterate over all imps in the request to perform the required + // imp.ext transformation. + request.Imp = []openrtb2.Imp{imp} + + for i := range request.Imp { + + var extBidder adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &extBidder); err != nil { + return nil, &errortypes.BadInput{Message: "Invalid ext.bidder"} + } + var extImpTargetVideo openrtb_ext.ExtImpTargetVideo + if err := jsonutil.Unmarshal(extBidder.Bidder, &extImpTargetVideo); err != nil { + return nil, err + } + + prebid := extBidder.Prebid + if prebid == nil { + prebid = &openrtb_ext.ExtImpPrebid{} + } + if prebid.StoredRequest == nil { + prebid.StoredRequest = &openrtb_ext.ExtStoredRequest{} + } + prebid.StoredRequest.ID = fmt.Sprintf("%d", extImpTargetVideo.PlacementId) + + var extMap map[string]json.RawMessage + if err := jsonutil.Unmarshal(imp.Ext, &extMap); err != nil { + return nil, &errortypes.BadInput{Message: fmt.Sprintf("error parsing imp.ext, err: %s", err)} + } + delete(extMap, "bidder") + + prebidRaw, err := jsonutil.Marshal(prebid) + if err != nil { + return nil, &errortypes.BadInput{Message: fmt.Sprintf("error building imp.ext.prebid, err: %s", err)} + } + extMap["prebid"] = prebidRaw + + extRaw, err := jsonutil.Marshal(extMap) + if err != nil { + return nil, &errortypes.BadInput{Message: fmt.Sprintf("error building imp.ext, err: %s", err)} + } + + request.Imp[i].Ext = extRaw + + } + + reqJSON, err := jsonutil.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(bidReq *openrtb2.BidRequest, unused *adapters.RequestData, httpRes *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(httpRes) { + return nil, nil + } + if statusError := adapters.CheckResponseStatusCodeForErrors(httpRes); statusError != nil { + return nil, []error{statusError} + } + + bidResp, errResp := prepareBidResponse(httpRes.Body) + if errResp != nil { + return nil, []error{errResp} + } + + br := adapters.NewBidderResponse() + + for _, sb := range bidResp.SeatBid { + for i := range sb.Bid { + bid := sb.Bid[i] + br.Bids = append(br.Bids, &adapters.TypedBid{Bid: &bid, BidType: openrtb_ext.BidTypeVideo}) + br.Currency = bidResp.Cur + } + } + return br, nil +} + +func prepareBidResponse(body []byte) (openrtb2.BidResponse, error) { + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(body, &response); err != nil { + return response, err + } + return response, nil +} + +func Builder(bidderName openrtb_ext.BidderName, cfg config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: cfg.Endpoint, + } + return bidder, nil +} diff --git a/adapters/targetVideo/targetvideo_test.go b/adapters/targetVideo/targetvideo_test.go new file mode 100644 index 0000000000..39ddd9d82b --- /dev/null +++ b/adapters/targetVideo/targetvideo_test.go @@ -0,0 +1,19 @@ +package targetVideo + +import ( + "testing" + + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/require" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderTargetVideo, config.Adapter{ + Endpoint: "http://localhost/pbs"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + require.NoError(t, buildErr, "Builder returned unexpected error") + + adapterstest.RunJSONBidderTest(t, "targetvideotest", bidder) +} diff --git a/adapters/targetVideo/targetvideotest/exemplary/app-video.json b/adapters/targetVideo/targetvideotest/exemplary/app-video.json new file mode 100644 index 0000000000..88557a1e46 --- /dev/null +++ b/adapters/targetVideo/targetvideotest/exemplary/app-video.json @@ -0,0 +1,116 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "app": { + "id": "appID", + "publisher": { + "id": "uniq_pub_id" + } + }, + "cur": ["EUR"], + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "bidder": { + "placementId": "77777" + } + } + } + ], + "device": { + "ua": "test-user-agent" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id-video", + "app": { + "id": "appID", + "publisher": { + "id": "uniq_pub_id" + } + }, + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "77777" + } + } + } + } + ], + "device": { + "ua": "test-user-agent" + }, + "cur": ["EUR"] + }, + "impIDs":["test-imp-id-video"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-video", + "seatbid": [ + { + "seat": "targetVideo", + "bid": [ + { + "id": "randomID", + "impid": "test-imp-id-video", + "price": 5.5, + "adid": "12345678", + "adm": "test-imp-id-video", + "cid": "789", + "crid": "12345678", + "h": 360, + "w": 640 + } + ] + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids" : [{ + "bid": { + "id": "randomID", + "adid": "12345678", + "impid": "test-imp-id-video", + "price": 5.5, + "adm": "test-imp-id-video", + "crid": "12345678", + "cid": "789", + "h": 360, + "w": 640 + }, + "type": "video" + }] + } + ] +} diff --git a/adapters/targetVideo/targetvideotest/exemplary/site-video.json b/adapters/targetVideo/targetvideotest/exemplary/site-video.json new file mode 100644 index 0000000000..fcb6e34ed3 --- /dev/null +++ b/adapters/targetVideo/targetvideotest/exemplary/site-video.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "cur": ["EUR"], + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "bidder": { + "placementId": "77777" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id-video", + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "77777" + } + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + }, + "cur": ["EUR"] + }, + "impIDs":["test-imp-id-video"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-video", + "seatbid": [ + { + "seat": "targetVideo", + "bid": [ + { + "id": "randomID", + "impid": "test-imp-id-video", + "price": 5.5, + "adm": "test-imp-id-video", + "cid": "789", + "crid": "12345678", + "h": 360, + "w": 640 + } + ] + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids" : [{ + "bid": { + "id": "randomID", + "impid": "test-imp-id-video", + "price": 5.5, + "adm": "test-imp-id-video", + "crid": "12345678", + "cid": "789", + "h": 360, + "w": 640 + }, + "type": "video" + }] + } + ] +} diff --git a/adapters/targetVideo/targetvideotest/supplemental/204.json b/adapters/targetVideo/targetvideotest/supplemental/204.json new file mode 100644 index 0000000000..c64d797b32 --- /dev/null +++ b/adapters/targetVideo/targetvideotest/supplemental/204.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "cur": ["EUR"], + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "bidder": { + "placementId": "77777" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id-video", + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "77777" + } + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + }, + "cur": ["EUR"] + }, + "impIDs":["test-imp-id-video"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/targetVideo/targetvideotest/supplemental/400.json b/adapters/targetVideo/targetvideotest/supplemental/400.json new file mode 100644 index 0000000000..e69838a3c1 --- /dev/null +++ b/adapters/targetVideo/targetvideotest/supplemental/400.json @@ -0,0 +1,90 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "cur": ["EUR"], + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "bidder": { + "placementId": "77777" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id-video", + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "77777" + } + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + }, + "cur": ["EUR"] + }, + "impIDs":["test-imp-id-video"] + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/targetVideo/targetvideotest/supplemental/ext-bidder-error.json b/adapters/targetVideo/targetvideotest/supplemental/ext-bidder-error.json new file mode 100644 index 0000000000..009d397e3f --- /dev/null +++ b/adapters/targetVideo/targetvideotest/supplemental/ext-bidder-error.json @@ -0,0 +1,37 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "Invalid ext.bidder", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "test-request-id-video", + "cur": ["EUR"], + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": "invalid-ext" + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + } + }, + "httpCalls": [] +} \ No newline at end of file diff --git a/adapters/targetVideo/targetvideotest/supplemental/no_seatbid.json b/adapters/targetVideo/targetvideotest/supplemental/no_seatbid.json new file mode 100644 index 0000000000..73321a5838 --- /dev/null +++ b/adapters/targetVideo/targetvideotest/supplemental/no_seatbid.json @@ -0,0 +1,91 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "cur": ["EUR"], + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "bidder": { + "placementId": "77777" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id-video", + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "77777" + } + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + }, + "cur": ["EUR"] + }, + "impIDs":["test-imp-id-video"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [{ + "currency": "USD" + }] +} diff --git a/adapters/targetVideo/targetvideotest/supplemental/overwrite-stored-request.json b/adapters/targetVideo/targetvideotest/supplemental/overwrite-stored-request.json new file mode 100644 index 0000000000..1d611a7810 --- /dev/null +++ b/adapters/targetVideo/targetvideotest/supplemental/overwrite-stored-request.json @@ -0,0 +1,127 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "cur": ["EUR"], + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "bidder": { + "placementId": "77777" + }, + "prebid": { + "storedrequest": { + "id": "existing-stored-req" + } + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id-video", + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "77777" + } + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + }, + "cur": ["EUR"] + }, + "impIDs": ["test-imp-id-video"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-video", + "seatbid": [ + { + "seat": "targetVideo", + "bid": [ + { + "id": "randomID", + "impid": "test-imp-id-video", + "price": 5.5, + "adm": "test-imp-id-video", + "cid": "789", + "crid": "12345678", + "h": 360, + "w": 640 + } + ] + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [{ + "bid": { + "id": "randomID", + "impid": "test-imp-id-video", + "price": 5.5, + "adm": "test-imp-id-video", + "crid": "12345678", + "cid": "789", + "h": 360, + "w": 640 + }, + "type": "video" + }] + } + ] +} diff --git a/adapters/targetVideo/targetvideotest/supplemental/preserve-imp-ext-fields.json b/adapters/targetVideo/targetvideotest/supplemental/preserve-imp-ext-fields.json new file mode 100644 index 0000000000..4db9285083 --- /dev/null +++ b/adapters/targetVideo/targetvideotest/supplemental/preserve-imp-ext-fields.json @@ -0,0 +1,130 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "cur": ["EUR"], + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "bidder": { + "placementId": "77777" + }, + "prebid": { + "is_rewarded_inventory": 1 + }, + "tid": "some-transaction-id", + "gpid": "/1234/main-player" + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id-video", + "imp": [ + { + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 360 + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "77777" + }, + "is_rewarded_inventory": 1 + }, + "tid": "some-transaction-id", + "gpid": "/1234/main-player" + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + }, + "cur": ["EUR"] + }, + "impIDs": ["test-imp-id-video"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-video", + "seatbid": [ + { + "seat": "targetVideo", + "bid": [ + { + "id": "randomID", + "impid": "test-imp-id-video", + "price": 5.5, + "adm": "test-imp-id-video", + "cid": "789", + "crid": "12345678", + "h": 360, + "w": 640 + } + ] + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [{ + "bid": { + "id": "randomID", + "impid": "test-imp-id-video", + "price": 5.5, + "adm": "test-imp-id-video", + "crid": "12345678", + "cid": "789", + "h": 360, + "w": 640 + }, + "type": "video" + }] + } + ] +} diff --git a/adapters/teads/teads.go b/adapters/teads/teads.go index 402392d1cc..81d6eb35ed 100644 --- a/adapters/teads/teads.go +++ b/adapters/teads/teads.go @@ -9,12 +9,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // Builder builds a new instance of the Teads adapter for the given bidder with the given config. diff --git a/adapters/teads/teads_test.go b/adapters/teads/teads_test.go index 8499e6f139..ce61f732c3 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/teal/params_test.go b/adapters/teal/params_test.go new file mode 100644 index 0000000000..34507b8967 --- /dev/null +++ b/adapters/teal/params_test.go @@ -0,0 +1,54 @@ +package teal + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/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.BidderTeal, 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-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderTeal, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed invalid params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"account":"abc"}`, + `{"account":"abc","placement":"def"}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"placement":"def"}`, + `{"account":123}`, + `{"account":""}`, + `{"account":"abc","placement":42}`, + `{"account":"abc","placement":""}`, +} diff --git a/adapters/teal/teal.go b/adapters/teal/teal.go new file mode 100644 index 0000000000..d46c5ab2ec --- /dev/null +++ b/adapters/teal/teal.go @@ -0,0 +1,363 @@ +package teal + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "strings" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +const ( + msgAccountValidation = "account parameter failed validation" + msgPlacementValidation = "placement parameter failed validation" + msgImpExtParseFmt = "Error parsing imp.ext for impression %s" + msgImpExtBidderParseFmt = "Error parsing imp.ext.bidder for impression %s" + msgMixedAccountFmt = "mixed-account requests are not supported: imp %q account %q differs from request account %q" +) + +// adapter is the Teal openrtb2 bidder. +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Teal adapter for the given bidder with +// the given config. +func Builder(_ openrtb_ext.BidderName, cfg config.Adapter, _ config.Server) (adapters.Bidder, error) { + return &adapter{endpoint: cfg.Endpoint}, nil +} + +// MakeRequests transforms the openrtb2.BidRequest into a single Teal-bound HTTP +// request body: +// +// 1. Each imp's bidder-slot is decoded into ExtImpTeal and validated for +// non-blank account and (when present) non-blank placement. +// 2. Failed imps are dropped; their parse / validation errors are collected. +// 3. The first surviving imp's account is propagated to Site.Publisher.ID and +// App.Publisher.ID. Later imps must use that same account; an imp with a +// divergent account is rejected (BadInput) and dropped. +// 4. Each surviving imp gets imp.ext.prebid.storedrequest.id = placement when +// placement is set. +// 5. Request.Ext.bids is stamped with {"pbs": 1}. +// +// If no imp survives validation, returns (nil, errs) without dispatching. +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + if len(request.Imp) == 0 { + return nil, nil + } + + modifiedImps := make([]openrtb2.Imp, 0, len(request.Imp)) + var errs []error + var account string + + for i := range request.Imp { + imp := request.Imp[i] + ext, err := parseImpExt(&imp) + if err != nil { + errs = append(errs, &errortypes.BadInput{Message: err.Error()}) + continue + } + if err := validateImpExt(ext); err != nil { + errs = append(errs, &errortypes.BadInput{Message: err.Error()}) + continue + } + + // All imps in a request must agree on account, which drives the single + // request-level publisher.id. The first valid imp establishes it; a later + // imp with a different account is rejected and dropped. + if account == "" { + account = ext.Account + } else if ext.Account != account { + errs = append(errs, &errortypes.BadInput{ + Message: fmt.Sprintf(msgMixedAccountFmt, imp.ID, ext.Account, account), + }) + continue + } + + modified, err := modifyImp(&imp, ext.Placement) + if err != nil { + errs = append(errs, &errortypes.BadInput{Message: err.Error()}) + continue + } + modifiedImps = append(modifiedImps, *modified) + } + + if len(modifiedImps) == 0 { + return nil, errs + } + + modifiedRequest, err := modifyBidRequest(request, account, modifiedImps) + if err != nil { + return nil, append(errs, err) + } + + body, err := jsonutil.Marshal(modifiedRequest) + if err != nil { + return nil, append(errs, err) + } + + return []*adapters.RequestData{{ + Method: http.MethodPost, + Uri: a.endpoint, + Body: body, + Headers: standardHeaders(), + ImpIDs: openrtb_ext.GetImpIDs(modifiedRequest.Imp), + }}, errs +} + +// parseImpExt decodes imp.ext.bidder into ExtImpTeal. +func parseImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpTeal, error) { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, fmt.Errorf(msgImpExtParseFmt, imp.ID) + } + var ext openrtb_ext.ExtImpTeal + if err := jsonutil.Unmarshal(bidderExt.Bidder, &ext); err != nil { + return nil, fmt.Errorf(msgImpExtBidderParseFmt, imp.ID) + } + return &ext, nil +} + +// validateImpExt requires a non-blank account and, when placement is present +// (non-nil), a non-blank placement. Absent placement is allowed. +func validateImpExt(ext *openrtb_ext.ExtImpTeal) error { + if isBlank(ext.Account) { + return errors.New(msgAccountValidation) + } + if ext.Placement != nil && isBlank(*ext.Placement) { + return errors.New(msgPlacementValidation) + } + return nil +} + +// isBlank reports whether s is empty or contains only whitespace. +func isBlank(s string) bool { + return strings.TrimSpace(s) == "" +} + +// modifyImp returns a copy of imp with imp.ext.prebid.storedrequest.id set to +// *placement. Returns the imp unchanged when placement is nil. Existing +// prebid or storedrequest sub-keys that are not JSON objects are tolerated by +// replacing them with fresh objects. +func modifyImp(imp *openrtb2.Imp, placement *string) (*openrtb2.Imp, error) { + if placement == nil { + return imp, nil + } + + ext, err := decodeJSONObject(imp.Ext) + if err != nil { + return nil, fmt.Errorf(msgImpExtParseFmt, imp.ID) + } + + prebid := decodeOrEmptyObject(ext["prebid"]) + storedRequest := decodeOrEmptyObject(prebid["storedrequest"]) + + placementJSON, err := jsonutil.Marshal(*placement) + if err != nil { + return nil, err + } + storedRequest["id"] = placementJSON + + storedRequestJSON, err := jsonutil.Marshal(storedRequest) + if err != nil { + return nil, err + } + prebid["storedrequest"] = storedRequestJSON + + prebidJSON, err := jsonutil.Marshal(prebid) + if err != nil { + return nil, err + } + ext["prebid"] = prebidJSON + + extJSON, err := jsonutil.Marshal(ext) + if err != nil { + return nil, err + } + + modified := *imp + modified.Ext = extJSON + return &modified, nil +} + +// decodeOrEmptyObject decodes raw as a JSON object map. Returns an empty map +// when raw is absent / "null" / not a JSON object. The returned map is NEVER +// nil — it is always safe to assign into. +func decodeOrEmptyObject(raw json.RawMessage) map[string]json.RawMessage { + out, _ := decodeJSONObject(raw) + return out +} + +// decodeJSONObject decodes raw into a JSON object map. Treats absent input +// AND the JSON literal `null` as "empty object". Returns the parse error +// untouched on invalid JSON or non-object root types so callers can surface a +// meaningful failure. The returned map is NEVER nil, even on error — callers +// can safely assign into it. +func decodeJSONObject(raw json.RawMessage) (map[string]json.RawMessage, error) { + if len(raw) == 0 { + return make(map[string]json.RawMessage), nil + } + var parsed map[string]json.RawMessage + if err := jsonutil.Unmarshal(raw, &parsed); err != nil { + return make(map[string]json.RawMessage), err + } + if parsed == nil { + return make(map[string]json.RawMessage), nil + } + return parsed, nil +} + +// modifyBidRequest applies the request-level mutations: +// +// - Site.Publisher.ID is overwritten with account when site is non-nil +// - App.Publisher.ID is overwritten with account when app is non-nil +// - Request.Ext.bids is stamped with {"pbs":1} +// +// Returns a value-copy with mutated fields; the caller's request is untouched. +func modifyBidRequest(request *openrtb2.BidRequest, account string, modifiedImps []openrtb2.Imp) (*openrtb2.BidRequest, error) { + modified := *request + modified.Imp = modifiedImps + + if request.Site != nil { + site := *request.Site + site.Publisher = clonePublisherWithID(site.Publisher, account) + modified.Site = &site + } + if request.App != nil { + app := *request.App + app.Publisher = clonePublisherWithID(app.Publisher, account) + modified.App = &app + } + + extJSON, err := mergeBidsPBSFlag(request.Ext) + if err != nil { + return nil, err + } + modified.Ext = extJSON + return &modified, nil +} + +// clonePublisherWithID returns a copy of publisher with ID overwritten, +// creating a fresh Publisher when publisher is nil. +func clonePublisherWithID(publisher *openrtb2.Publisher, id string) *openrtb2.Publisher { + if publisher == nil { + return &openrtb2.Publisher{ID: id} + } + pub := *publisher + pub.ID = id + return &pub +} + +// mergeBidsPBSFlag returns existingExt with the "bids" property set to +// {"pbs":1}; other ext fields are preserved. The "pbs":1 marker is a Teal-side +// reporting/billing signal — it tells Teal's exchange the request is being +// routed via prebid-server, distinguishing it from direct integrations. +func mergeBidsPBSFlag(existingExt json.RawMessage) (json.RawMessage, error) { + ext, err := decodeJSONObject(existingExt) + if err != nil { + return nil, fmt.Errorf("teal: failed parsing request.ext: %w", err) + } + // Overwrite any caller-provided ext.bids: the {"pbs":1} marker must be + // authoritative for Teal's reporting/billing pipeline, so a value set by the + // publisher or upstream middleware is intentionally replaced, not merged. + ext["bids"] = json.RawMessage(`{"pbs":1}`) + return jsonutil.Marshal(ext) +} + +// MakeBids parses the Teal bid response body and packages the bids into a +// BidderResponse. Status handling follows the canonical adapters helpers: +// 204 → no-content shortcut, 4xx/5xx → BadServerResponse, 200 → parse body. +// Bids whose media type cannot be resolved from the matching imp are skipped +// and their error collected, rather than silently mis-typed as banner. +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: err.Error()}} + } + + impsByID := make(map[string]openrtb2.Imp, len(request.Imp)) + for _, imp := range request.Imp { + impsByID[imp.ID] = imp + } + + bidderResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if bidResponse.Cur != "" { + bidderResponse.Currency = bidResponse.Cur + } + var errs []error + for _, seatBid := range bidResponse.SeatBid { + for i := range seatBid.Bid { + bid := &seatBid.Bid[i] + bidType, err := getBidType(bid, impsByID) + if err != nil { + errs = append(errs, err) + continue + } + bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{ + Bid: bid, + BidType: bidType, + }) + } + } + return bidderResponse, errs +} + +// getBidType resolves the bid's media type. Teal declares multiformat-supported, +// so a single impression can carry more than one media type (e.g. banner+video); +// introspecting the imp alone cannot disambiguate which format a given bid is for. +// The authoritative signal is the response's own bid.mtype (OpenRTB 2.6), so it is +// consulted first. +// +// Only when the response omits mtype does getBidType fall back to introspecting the +// matching impression, looked up by ID via impsByID (built once in MakeBids to avoid +// a per-bid scan of request.Imp), in banner > video > native order. Audio is omitted +// because it is not in Teal's declared capabilities. +// +// When neither the bid's mtype nor a matching imp yields a recognized media type, +// getBidType returns an error so MakeBids can skip the bid and surface the problem in +// logs rather than silently mis-typing it. +func getBidType(bid *openrtb2.Bid, impsByID map[string]openrtb2.Imp) (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 + } + if imp, ok := impsByID[bid.ImpID]; ok { + switch { + case imp.Banner != nil: + return openrtb_ext.BidTypeBanner, nil + case imp.Video != nil: + return openrtb_ext.BidTypeVideo, nil + case imp.Native != nil: + return openrtb_ext.BidTypeNative, nil + } + } + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("failed to determine bid type for imp %q", bid.ImpID), + } +} + +// standardHeaders returns the headers Teal expects on every outbound request. +func standardHeaders() http.Header { + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + return headers +} diff --git a/adapters/teal/teal_test.go b/adapters/teal/teal_test.go new file mode 100644 index 0000000000..7ca4ced1d5 --- /dev/null +++ b/adapters/teal/teal_test.go @@ -0,0 +1,282 @@ +package teal + +import ( + "encoding/json" + "errors" + "net/http" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + testEndpoint = "https://test.example.com/bid" + testAccount = "test-account" + testRequestID = "test-request-banner" +) + +// End-to-end MakeRequests/MakeBids behavior is exercised by the JSON fixtures +// under tealtest/exemplary and tealtest/supplemental. The Go tests below cover +// only what fixtures cannot: the Go error-TYPE contract (BadInput vs +// BadServerResponse), short-circuit edges, and error branches of unexported +// helpers that are unreachable through MakeRequests. + +func TestJsonSamples(t *testing.T) { + bidder, err := Builder(openrtb_ext.BidderTeal, config.Adapter{Endpoint: testEndpoint}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + require.NoError(t, err, "Builder returned unexpected error") + adapterstest.RunJSONBidderTest(t, "tealtest", bidder) +} + +// TestErrorClassification pins the error-type contract, which the JSON fixtures +// cannot verify (they compare error messages only): MakeRequests parse / +// validation / account-divergence errors are *errortypes.BadInput; MakeBids +// transport errors are BadInput for 4xx and *errortypes.BadServerResponse for +// 5xx and unparseable bodies. +func TestErrorClassification(t *testing.T) { + bidder := newTealBidder(t) + + t.Run("imp.ext parse error is BadInput", func(t *testing.T) { + imp := openrtb2.Imp{ + ID: "impId", + Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}, + Ext: json.RawMessage(`[]`), + } + requests, errs := bidder.MakeRequests(givenBidRequest(imp), &adapters.ExtraRequestInfo{}) + assert.Nil(t, requests) + require.Len(t, errs, 1) + assert.True(t, isBadInputErr(errs[0]), "got %T", errs[0]) + assert.Contains(t, errs[0].Error(), "Error parsing imp.ext for impression impId") + }) + + t.Run("imp.ext bidder field malformed is BadInput", func(t *testing.T) { + imp := givenBannerImp("impId", json.RawMessage(`{"bidder":[]}`)) + requests, errs := bidder.MakeRequests(givenBidRequest(imp), &adapters.ExtraRequestInfo{}) + assert.Nil(t, requests) + require.Len(t, errs, 1) + assert.True(t, isBadInputErr(errs[0]), "got %T", errs[0]) + assert.Contains(t, errs[0].Error(), "Error parsing imp.ext.bidder for impression impId") + }) + + t.Run("blank account is BadInput", func(t *testing.T) { + imp := givenBannerImp("imp1", givenImpExt(t, " ", strPtr("p"))) + requests, errs := bidder.MakeRequests(givenBidRequest(imp), &adapters.ExtraRequestInfo{}) + assert.Nil(t, requests) + require.Len(t, errs, 1) + assert.True(t, isBadInputErr(errs[0]), "got %T", errs[0]) + assert.Equal(t, msgAccountValidation, errs[0].Error()) + }) + + t.Run("blank placement is BadInput", func(t *testing.T) { + imp := givenBannerImp("imp1", givenImpExt(t, "acct", strPtr(" "))) + requests, errs := bidder.MakeRequests(givenBidRequest(imp), &adapters.ExtraRequestInfo{}) + assert.Nil(t, requests) + require.Len(t, errs, 1) + assert.True(t, isBadInputErr(errs[0]), "got %T", errs[0]) + assert.Equal(t, msgPlacementValidation, errs[0].Error()) + }) + + t.Run("divergent account is BadInput", func(t *testing.T) { + first := givenBannerImp("imp1", givenImpExt(t, "acct-a", strPtr("p1"))) + second := givenBannerImp("imp2", givenImpExt(t, "acct-b", strPtr("p2"))) + requests, errs := bidder.MakeRequests(givenBidRequest(first, second), &adapters.ExtraRequestInfo{}) + require.Len(t, requests, 1, "first imp still ships") + require.Len(t, errs, 1) + assert.True(t, isBadInputErr(errs[0]), "got %T", errs[0]) + assert.Contains(t, errs[0].Error(), "mixed-account requests are not supported") + }) + + t.Run("malformed request.ext propagates parse error", func(t *testing.T) { + imp := givenBannerImp("imp1", givenImpExt(t, testAccount, nil)) + req := givenBidRequest(imp) + req.Ext = json.RawMessage(`{"prebid":}`) // syntactically invalid + requests, errs := bidder.MakeRequests(req, &adapters.ExtraRequestInfo{}) + assert.Nil(t, requests) + require.NotEmpty(t, errs) + assert.Contains(t, errs[len(errs)-1].Error(), "failed parsing request.ext") + }) + + t.Run("MakeBids 4xx is BadInput", func(t *testing.T) { + resp, errs := makeBidsCall(t, bidder, &openrtb2.BidRequest{}, http.StatusBadRequest, []byte(`{}`)) + assert.Nil(t, resp) + require.Len(t, errs, 1) + assert.True(t, isBadInputErr(errs[0]), "got %T", errs[0]) + }) + + t.Run("MakeBids 5xx is BadServerResponse", func(t *testing.T) { + resp, errs := makeBidsCall(t, bidder, &openrtb2.BidRequest{}, http.StatusInternalServerError, []byte(`{}`)) + assert.Nil(t, resp) + require.Len(t, errs, 1) + assert.True(t, isBadServerErr(errs[0]), "got %T", errs[0]) + }) + + t.Run("MakeBids unparseable body is BadServerResponse", func(t *testing.T) { + resp, errs := makeBidsCall(t, bidder, &openrtb2.BidRequest{}, http.StatusOK, []byte("not-json")) + assert.Nil(t, resp) + require.Len(t, errs, 1) + assert.True(t, isBadServerErr(errs[0]), "got %T", errs[0]) + }) +} + +// TestMakeRequests_NoImps — empty Imp slice returns (nil, nil) before any work +// happens. +func TestMakeRequests_NoImps(t *testing.T) { + bidder := newTealBidder(t) + requests, errs := bidder.MakeRequests(&openrtb2.BidRequest{ID: "req"}, &adapters.ExtraRequestInfo{}) + assert.Nil(t, requests) + assert.Nil(t, errs) +} + +// TestGetBidType_Undeterminable — getBidType returns an explicit error (not a +// silent banner default) when the imp is missing or declares no media type, so +// MakeBids can skip the bid and surface the issue in logs. +func TestGetBidType_Undeterminable(t *testing.T) { + bid := &openrtb2.Bid{ImpID: "imp1"} + + t.Run("imp not found", func(t *testing.T) { + _, err := getBidType(bid, map[string]openrtb2.Imp{}) + require.Error(t, err) + assert.Contains(t, err.Error(), `failed to determine bid type for imp "imp1"`) + }) + + t.Run("imp has no media type", func(t *testing.T) { + imp := openrtb2.Imp{ID: "imp1"} + _, err := getBidType(bid, map[string]openrtb2.Imp{imp.ID: imp}) + require.Error(t, err) + assert.Contains(t, err.Error(), `failed to determine bid type for imp "imp1"`) + }) +} + +// TestModifyImp_MalformedExt — modifyImp's parse-error branch. Unreachable via +// MakeRequests (parseImpExt rejects non-object imp.ext first), so it cannot be +// a fixture. +func TestModifyImp_MalformedExt(t *testing.T) { + imp := &openrtb2.Imp{ID: "broken", Ext: json.RawMessage(`not-json`)} + got, err := modifyImp(imp, strPtr("p")) + assert.Nil(t, got) + require.Error(t, err) + assert.Contains(t, err.Error(), "Error parsing imp.ext for impression broken") +} + +// TestDecodeOrEmptyObject — the non-object branch is unreachable via +// MakeRequests (parseImpExt rejects those shapes first); the returned map must +// never be nil so callers can assign into it. +func TestDecodeOrEmptyObject(t *testing.T) { + t.Run("empty raw returns empty map", func(t *testing.T) { + out := decodeOrEmptyObject(nil) + assert.NotNil(t, out) + assert.Empty(t, out) + }) + + t.Run("non-object input returns empty map", func(t *testing.T) { + out := decodeOrEmptyObject(json.RawMessage(`[1,2,3]`)) + assert.NotNil(t, out) + assert.Empty(t, out) + }) + + t.Run("valid object input returns populated map", func(t *testing.T) { + out := decodeOrEmptyObject(json.RawMessage(`{"a":1,"b":"two"}`)) + assert.Len(t, out, 2) + assert.JSONEq(t, `1`, string(out["a"])) + assert.JSONEq(t, `"two"`, string(out["b"])) + }) +} + +// TestMergeBidsPBSFlag — pins the null-handling contract: a JSON literal `null` +// (or absent) ext must route through decodeJSONObject so the receiver map is +// non-nil before `ext["bids"] = ...`, which would otherwise panic with +// "assignment to entry in nil map". +func TestMergeBidsPBSFlag(t *testing.T) { + t.Run("null ext treated as empty object", func(t *testing.T) { + out, err := mergeBidsPBSFlag(json.RawMessage(`null`)) + require.NoError(t, err) + require.NotNil(t, out) + + var decoded map[string]json.RawMessage + require.NoError(t, json.Unmarshal(out, &decoded)) + assert.Len(t, decoded, 1, "null input should produce just the bids stamp") + assert.JSONEq(t, `{"pbs":1}`, string(decoded["bids"])) + }) + + t.Run("malformed ext returns wrapped error", func(t *testing.T) { + out, err := mergeBidsPBSFlag(json.RawMessage(`{"bids":`)) + assert.Nil(t, out) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed parsing request.ext") + }) +} + +// --------------------------------------------------------------------------- +// Test helpers +// --------------------------------------------------------------------------- + +// strPtr returns a pointer to s. Used for the *string Placement field. +func strPtr(s string) *string { + return &s +} + +// newTealBidder builds the adapter via the canonical Builder. +func newTealBidder(t *testing.T) adapters.Bidder { + t.Helper() + bidder, err := Builder(openrtb_ext.BidderTeal, config.Adapter{Endpoint: testEndpoint}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + require.NoError(t, err) + require.NotNil(t, bidder) + return bidder +} + +// givenImpExt produces the imp.ext shape Teal expects: {"bidder": ExtImpTeal}. +func givenImpExt(t *testing.T, account string, placement *string) json.RawMessage { + t.Helper() + inner := openrtb_ext.ExtImpTeal{Account: account, Placement: placement} + innerJSON, err := json.Marshal(inner) + require.NoError(t, err) + wrapper := map[string]json.RawMessage{"bidder": innerJSON} + out, err := json.Marshal(wrapper) + require.NoError(t, err) + return out +} + +// givenBannerImp returns a single banner imp with the supplied id and ext. +func givenBannerImp(id string, ext json.RawMessage) openrtb2.Imp { + return openrtb2.Imp{ + ID: id, + Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}, + Ext: ext, + } +} + +// givenBidRequest returns a minimal site-rooted BidRequest with the given imps. +func givenBidRequest(imps ...openrtb2.Imp) *openrtb2.BidRequest { + return &openrtb2.BidRequest{ + ID: testRequestID, + Imp: imps, + Site: &openrtb2.Site{ID: "demo-site", Publisher: &openrtb2.Publisher{ID: "demo-publisher"}}, + } +} + +// makeBidsCall wires a ResponseData and invokes MakeBids. +func makeBidsCall(t *testing.T, bidder adapters.Bidder, request *openrtb2.BidRequest, status int, body []byte) (*adapters.BidderResponse, []error) { + t.Helper() + return bidder.MakeBids(request, &adapters.RequestData{Method: http.MethodPost, Uri: testEndpoint}, + &adapters.ResponseData{StatusCode: status, Body: body}) +} + +// isBadInputErr returns true if err is or wraps an *errortypes.BadInput. +func isBadInputErr(err error) bool { + var target *errortypes.BadInput + return errors.As(err, &target) +} + +// isBadServerErr returns true if err is or wraps an *errortypes.BadServerResponse. +func isBadServerErr(err error) bool { + var target *errortypes.BadServerResponse + return errors.As(err, &target) +} diff --git a/adapters/teal/tealtest/exemplary/app-publisher-rewrite.json b/adapters/teal/tealtest/exemplary/app-publisher-rewrite.json new file mode 100644 index 0000000000..25a46fb874 --- /dev/null +++ b/adapters/teal/tealtest/exemplary/app-publisher-rewrite.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + } + } + ], + "app": { + "id": "demo-app", + "name": "Demo App", + "bundle": "com.example.demoapp", + "publisher": { + "id": "demo-publisher" + } + }, + "device": { + "ua": "Mozilla/5.0 (Linux; Android 11) AppleWebKit/537.36", + "ip": "192.0.2.10", + "language": "en", + "ifa": "demo-ifa" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "app": { + "id": "demo-app", + "name": "Demo App", + "bundle": "com.example.demoapp", + "publisher": { + "id": "test-account" + } + }, + "device": { + "ua": "Mozilla/5.0 (Linux; Android 11) AppleWebKit/537.36", + "ip": "192.0.2.10", + "language": "en", + "ifa": "demo-ifa" + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "app-bid-1", + "impid": "test-imp-banner", + "price": 3.10, + "adm": "
app-banner
", + "w": 300, + "h": 250, + "crid": "app-creative-9" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "app-bid-1", + "impid": "test-imp-banner", + "price": 3.10, + "adm": "
app-banner
", + "w": 300, + "h": 250, + "crid": "app-creative-9" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/exemplary/existing-request-ext.json b/adapters/teal/tealtest/exemplary/existing-request-ext.json new file mode 100644 index 0000000000..7c21c085f0 --- /dev/null +++ b/adapters/teal/tealtest/exemplary/existing-request-ext.json @@ -0,0 +1,135 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + }, + "ext": { + "tealcustom": "preserve-me", + "prebid": { + "channel": { + "name": "web" + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "ext": { + "bids": { + "pbs": 1 + }, + "prebid": { + "channel": { + "name": "web" + } + }, + "tealcustom": "preserve-me" + } + }, + "impIDs": ["test-imp-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "ext-bid", + "impid": "test-imp-banner", + "price": 1.75, + "adm": "
ext-preserved
", + "w": 300, + "h": 250, + "crid": "ext-creative" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "ext-bid", + "impid": "test-imp-banner", + "price": 1.75, + "adm": "
ext-preserved
", + "w": 300, + "h": 250, + "crid": "ext-creative" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/exemplary/multi-format-imp-mtype.json b/adapters/teal/tealtest/exemplary/multi-format-imp-mtype.json new file mode 100644 index 0000000000..e8114b1969 --- /dev/null +++ b/adapters/teal/tealtest/exemplary/multi-format-imp-mtype.json @@ -0,0 +1,173 @@ +{ + "mockBidRequest": { + "id": "test-request-multi-format-mtype", + "imp": [ + { + "id": "test-imp-multi-format", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480 + }, + "native": { + "request": "{\"ver\":\"1.2\"}" + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement-multi" + } + } + } + ], + "site": { + "id": "demo-site", + "publisher": { + "id": "demo-publisher" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-multi-format-mtype", + "imp": [ + { + "id": "test-imp-multi-format", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480 + }, + "native": { + "request": "{\"ver\":\"1.2\"}" + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement-multi" + }, + "prebid": { + "storedrequest": { + "id": "test-placement-multi" + } + } + } + } + ], + "site": { + "id": "demo-site", + "publisher": { + "id": "test-account" + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-multi-format"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-multi-format-mtype", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid-banner", + "impid": "test-imp-multi-format", + "price": 1.75, + "adm": "
Teal Banner Ad
", + "mtype": 1, + "crid": "creative-banner" + }, + { + "id": "bid-video", + "impid": "test-imp-multi-format", + "price": 2.10, + "adm": "Teal Video Ad", + "mtype": 2, + "crid": "creative-video" + }, + { + "id": "bid-native", + "impid": "test-imp-multi-format", + "price": 0.90, + "adm": "{\"native\":{\"assets\":[]}}", + "mtype": 4, + "crid": "creative-native" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-banner", + "impid": "test-imp-multi-format", + "price": 1.75, + "adm": "
Teal Banner Ad
", + "mtype": 1, + "crid": "creative-banner" + }, + "type": "banner" + }, + { + "bid": { + "id": "bid-video", + "impid": "test-imp-multi-format", + "price": 2.10, + "adm": "Teal Video Ad", + "mtype": 2, + "crid": "creative-video" + }, + "type": "video" + }, + { + "bid": { + "id": "bid-native", + "impid": "test-imp-multi-format", + "price": 0.90, + "adm": "{\"native\":{\"assets\":[]}}", + "mtype": 4, + "crid": "creative-native" + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/exemplary/multi-format-imp.json b/adapters/teal/tealtest/exemplary/multi-format-imp.json new file mode 100644 index 0000000000..534711f492 --- /dev/null +++ b/adapters/teal/tealtest/exemplary/multi-format-imp.json @@ -0,0 +1,131 @@ +{ + "mockBidRequest": { + "id": "test-request-multi-format", + "imp": [ + { + "id": "test-imp-multi-format", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement-multi" + } + } + } + ], + "site": { + "id": "demo-site", + "publisher": { + "id": "demo-publisher" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-multi-format", + "imp": [ + { + "id": "test-imp-multi-format", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement-multi" + }, + "prebid": { + "storedrequest": { + "id": "test-placement-multi" + } + } + } + } + ], + "site": { + "id": "demo-site", + "publisher": { + "id": "test-account" + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-multi-format"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-multi-format", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid-multi-format", + "impid": "test-imp-multi-format", + "price": 1.75, + "adm": "
Teal Multi-Format Ad
", + "w": 300, + "h": 250, + "crid": "creative-multi" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-multi-format", + "impid": "test-imp-multi-format", + "price": 1.75, + "adm": "
Teal Multi-Format Ad
", + "w": 300, + "h": 250, + "crid": "creative-multi" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/exemplary/multi-imp-same-account.json b/adapters/teal/tealtest/exemplary/multi-imp-same-account.json new file mode 100644 index 0000000000..978b639a14 --- /dev/null +++ b/adapters/teal/tealtest/exemplary/multi-imp-same-account.json @@ -0,0 +1,181 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "shared-account", + "placement": "placement-1" + } + } + }, + { + "id": "test-imp-2", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "account": "shared-account", + "placement": "placement-2" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "shared-account", + "placement": "placement-1" + }, + "prebid": { + "storedrequest": { + "id": "placement-1" + } + } + } + }, + { + "id": "test-imp-2", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "account": "shared-account", + "placement": "placement-2" + }, + "prebid": { + "storedrequest": { + "id": "placement-2" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "shared-account" + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-1", "test-imp-2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid-1", + "impid": "test-imp-1", + "price": 1.10, + "adm": "
imp1
", + "w": 300, + "h": 250, + "crid": "c1" + }, + { + "id": "bid-2", + "impid": "test-imp-2", + "price": 0.80, + "adm": "
imp2
", + "w": 728, + "h": 90, + "crid": "c2" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "test-imp-1", + "price": 1.10, + "adm": "
imp1
", + "w": 300, + "h": 250, + "crid": "c1" + }, + "type": "banner" + }, + { + "bid": { + "id": "bid-2", + "impid": "test-imp-2", + "price": 0.80, + "adm": "
imp2
", + "w": 728, + "h": 90, + "crid": "c2" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/exemplary/native-imp.json b/adapters/teal/tealtest/exemplary/native-imp.json new file mode 100644 index 0000000000..10012c7001 --- /dev/null +++ b/adapters/teal/tealtest/exemplary/native-imp.json @@ -0,0 +1,81 @@ +{ + "mockBidRequest": { + "id": "test-request-native", + "imp": [ + { + "id": "test-imp-native", + "native": { + "request": "{\"ver\":\"1.1\"}" + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement-native" + } + } + } + ], + "site": { + "id": "demo-site", + "publisher": {"id": "demo-publisher"} + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-native", + "imp": [ + { + "id": "test-imp-native", + "native": {"request": "{\"ver\":\"1.1\"}"}, + "ext": { + "bidder": {"account": "test-account", "placement": "test-placement-native"}, + "prebid": {"storedrequest": {"id": "test-placement-native"}} + } + } + ], + "site": {"id": "demo-site", "publisher": {"id": "test-account"}}, + "ext": {"bids": {"pbs": 1}} + }, + "impIDs": ["test-imp-native"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-native", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid-native-1", + "impid": "test-imp-native", + "price": 1.0, + "adm": "{\"native\":{\"assets\":[]}}" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-native-1", + "impid": "test-imp-native", + "price": 1.0, + "adm": "{\"native\":{\"assets\":[]}}" + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/exemplary/placement-absent.json b/adapters/teal/tealtest/exemplary/placement-absent.json new file mode 100644 index 0000000000..3271695bb5 --- /dev/null +++ b/adapters/teal/tealtest/exemplary/placement-absent.json @@ -0,0 +1,114 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid-no-placement", + "impid": "test-imp-banner", + "price": 0.95, + "adm": "
no-placement
", + "w": 300, + "h": 250, + "crid": "creative-np" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-no-placement", + "impid": "test-imp-banner", + "price": 0.95, + "adm": "
no-placement
", + "w": 300, + "h": 250, + "crid": "creative-np" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/exemplary/preserves-existing-imp-ext-prebid.json b/adapters/teal/tealtest/exemplary/preserves-existing-imp-ext-prebid.json new file mode 100644 index 0000000000..daf2d0c2e7 --- /dev/null +++ b/adapters/teal/tealtest/exemplary/preserves-existing-imp-ext-prebid.json @@ -0,0 +1,131 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "foo": "bar", + "keyword": "keep-me", + "storedrequest": { + "unrelated": "value" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "foo": "bar", + "keyword": "keep-me", + "storedrequest": { + "unrelated": "value", + "id": "test-placement300x250" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid-1", + "impid": "test-imp-banner", + "price": 1.50, + "adm": "
ad
", + "w": 300, + "h": 250, + "crid": "c1" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "test-imp-banner", + "price": 1.50, + "adm": "
ad
", + "w": 300, + "h": 250, + "crid": "c1" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/exemplary/simple-banner.json b/adapters/teal/tealtest/exemplary/simple-banner.json new file mode 100644 index 0000000000..b143c66ed8 --- /dev/null +++ b/adapters/teal/tealtest/exemplary/simple-banner.json @@ -0,0 +1,171 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", + "ip": "192.0.2.1", + "language": "en", + "dnt": 0 + }, + "user": { + "id": "demo-user" + }, + "regs": { + "ext": { + "gdpr": 0 + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", + "ip": "192.0.2.1", + "language": "en", + "dnt": 0 + }, + "user": { + "id": "demo-user" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-imp-banner", + "impid": "test-imp-banner", + "price": 2.50, + "adm": "
Teal Demo Ad
", + "w": 300, + "h": 250, + "crid": "demo-creative-123", + "exp": 300, + "ext": { + "origbidcpm": 2.50, + "origbidcur": "USD", + "prebid": { + "type": "banner", + "meta": { + "adaptercode": "teal" + } + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-imp-banner", + "impid": "test-imp-banner", + "price": 2.50, + "adm": "
Teal Demo Ad
", + "w": 300, + "h": 250, + "crid": "demo-creative-123", + "exp": 300, + "ext": { + "origbidcpm": 2.50, + "origbidcur": "USD", + "prebid": { + "type": "banner", + "meta": { + "adaptercode": "teal" + } + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/exemplary/site-no-publisher.json b/adapters/teal/tealtest/exemplary/site-no-publisher.json new file mode 100644 index 0000000000..c4f4415439 --- /dev/null +++ b/adapters/teal/tealtest/exemplary/site-no-publisher.json @@ -0,0 +1,89 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + {"w": 300, "h": 250} + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": {"format": [{"w": 300, "h": 250}]}, + "ext": { + "bidder": {"account": "test-account", "placement": "test-placement300x250"}, + "prebid": {"storedrequest": {"id": "test-placement300x250"}} + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "publisher": {"id": "test-account"} + }, + "ext": {"bids": {"pbs": 1}} + }, + "impIDs": ["test-imp-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid-1", + "impid": "test-imp-banner", + "price": 2.0, + "w": 300, + "h": 250 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "test-imp-banner", + "price": 2.0, + "w": 300, + "h": 250 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/exemplary/video-imp.json b/adapters/teal/tealtest/exemplary/video-imp.json new file mode 100644 index 0000000000..de91ee3235 --- /dev/null +++ b/adapters/teal/tealtest/exemplary/video-imp.json @@ -0,0 +1,121 @@ +{ + "mockBidRequest": { + "id": "test-request-video", + "imp": [ + { + "id": "test-imp-video", + "video": { + "mimes": ["video/mp4"], + "w": 640, + "h": 480, + "minduration": 5, + "maxduration": 30, + "protocols": [2, 3, 5, 6] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement-video" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-video", + "imp": [ + { + "id": "test-imp-video", + "video": { + "mimes": ["video/mp4"], + "minduration": 5, + "maxduration": 30, + "protocols": [2, 3, 5, 6], + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement-video" + }, + "prebid": { + "storedrequest": { + "id": "test-placement-video" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-video"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-video", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "video-bid-1", + "impid": "test-imp-video", + "price": 4.50, + "adm": "", + "w": 640, + "h": 480, + "crid": "video-creative-22" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "video-bid-1", + "impid": "test-imp-video", + "price": 4.50, + "adm": "", + "w": 640, + "h": 480, + "crid": "video-creative-22" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/supplemental/bid-unmatched-imp-skipped.json b/adapters/teal/tealtest/supplemental/bid-unmatched-imp-skipped.json new file mode 100644 index 0000000000..fd6db866a6 --- /dev/null +++ b/adapters/teal/tealtest/supplemental/bid-unmatched-imp-skipped.json @@ -0,0 +1,134 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "good-bid", + "impid": "test-imp-banner", + "price": 1.25, + "adm": "
kept
", + "w": 300, + "h": 250, + "crid": "creative-1" + }, + { + "id": "orphan-bid", + "impid": "no-such-imp", + "price": 0.99, + "adm": "
skipped
", + "crid": "creative-2" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "good-bid", + "impid": "test-imp-banner", + "price": 1.25, + "adm": "
kept
", + "w": 300, + "h": 250, + "crid": "creative-1" + }, + "type": "banner" + } + ] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "failed to determine bid type for imp \"no-such-imp\"", + "comparison": "literal" + } + ] +} diff --git a/adapters/teal/tealtest/supplemental/both-site-and-app.json b/adapters/teal/tealtest/supplemental/both-site-and-app.json new file mode 100644 index 0000000000..c19fee1396 --- /dev/null +++ b/adapters/teal/tealtest/supplemental/both-site-and-app.json @@ -0,0 +1,135 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "site-pub" + } + }, + "app": { + "id": "demo-app", + "bundle": "com.demo.app", + "publisher": { + "id": "app-pub" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "app": { + "id": "demo-app", + "bundle": "com.demo.app", + "publisher": { + "id": "test-account" + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid-1", + "impid": "test-imp-banner", + "price": 1.50, + "adm": "
ad
", + "w": 300, + "h": 250, + "crid": "c1" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "test-imp-banner", + "price": 1.50, + "adm": "
ad
", + "w": 300, + "h": 250, + "crid": "c1" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/supplemental/empty-seatbid.json b/adapters/teal/tealtest/supplemental/empty-seatbid.json new file mode 100644 index 0000000000..c7b2888b70 --- /dev/null +++ b/adapters/teal/tealtest/supplemental/empty-seatbid.json @@ -0,0 +1,83 @@ +{ + "mockBidRequest": { + "id": "test-request-empty-seatbid", + "imp": [ + { + "id": "test-imp-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account" + } + } + } + ], + "site": { + "id": "demo-site", + "publisher": { + "id": "demo-publisher" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-empty-seatbid", + "imp": [ + { + "id": "test-imp-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account" + } + } + } + ], + "site": { + "id": "demo-site", + "publisher": { + "id": "test-account" + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-empty-seatbid", + "cur": "USD", + "seatbid": [] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ] +} diff --git a/adapters/teal/tealtest/supplemental/malformed-body.json b/adapters/teal/tealtest/supplemental/malformed-body.json new file mode 100644 index 0000000000..1c535d52bc --- /dev/null +++ b/adapters/teal/tealtest/supplemental/malformed-body.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "device": { + "dnt": 0, + "ip": "192.0.2.1", + "language": "en", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "id": "test-request-banner", + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + }, + "id": "test-imp-banner" + } + ], + "regs": { + "ext": { + "gdpr": 0 + } + }, + "site": { + "domain": "example.com", + "id": "demo-site", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + }, + "user": { + "id": "demo-user" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", + "ip": "192.0.2.1", + "language": "en", + "dnt": 0 + }, + "user": { + "id": "demo-user" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": [ + "test-imp-banner" + ] + }, + "mockResponse": { + "status": 200, + "body": "this is not json" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} diff --git a/adapters/teal/tealtest/supplemental/mixed-imp-partial-failure.json b/adapters/teal/tealtest/supplemental/mixed-imp-partial-failure.json new file mode 100644 index 0000000000..7943c744a5 --- /dev/null +++ b/adapters/teal/tealtest/supplemental/mixed-imp-partial-failure.json @@ -0,0 +1,156 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + } + }, + { + "id": "test-imp-bad", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "account": "", + "placement": "test-placement728x90" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", + "ip": "192.0.2.1", + "language": "en", + "dnt": 0 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", + "ip": "192.0.2.1", + "language": "en", + "dnt": 0 + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "good-bid", + "impid": "test-imp-banner", + "price": 1.25, + "adm": "
partial-success
", + "w": 300, + "h": 250, + "crid": "creative-1" + } + ] + } + ] + } + } + } + ], + "expectedMakeRequestsErrors": [ + { + "value": "account parameter failed validation", + "comparison": "literal" + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "good-bid", + "impid": "test-imp-banner", + "price": 1.25, + "adm": "
partial-success
", + "w": 300, + "h": 250, + "crid": "creative-1" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/supplemental/multi-imp-divergent-account-rejected.json b/adapters/teal/tealtest/supplemental/multi-imp-divergent-account-rejected.json new file mode 100644 index 0000000000..a4df97da64 --- /dev/null +++ b/adapters/teal/tealtest/supplemental/multi-imp-divergent-account-rejected.json @@ -0,0 +1,144 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "first-account", + "placement": "placement-1" + } + } + }, + { + "id": "test-imp-2", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "account": "second-account", + "placement": "placement-2" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "first-account", + "placement": "placement-1" + }, + "prebid": { + "storedrequest": { + "id": "placement-1" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "first-account" + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid-1", + "impid": "test-imp-1", + "price": 1.10, + "adm": "
imp1
", + "w": 300, + "h": 250, + "crid": "c1" + } + ] + } + ] + } + } + } + ], + "expectedMakeRequestsErrors": [ + { + "value": "mixed-account requests are not supported: imp \"test-imp-2\" account \"second-account\" differs from request account \"first-account\"", + "comparison": "literal" + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "test-imp-1", + "price": 1.10, + "adm": "
imp1
", + "w": 300, + "h": 250, + "crid": "c1" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/supplemental/multi-seatbid.json b/adapters/teal/tealtest/supplemental/multi-seatbid.json new file mode 100644 index 0000000000..964b37c14d --- /dev/null +++ b/adapters/teal/tealtest/supplemental/multi-seatbid.json @@ -0,0 +1,194 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "multi-acct", + "placement": "pb" + } + } + }, + { + "id": "imp-video", + "video": { + "mimes": ["video/mp4"] + }, + "ext": { + "bidder": { + "account": "multi-acct", + "placement": "pv" + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "multi-acct", + "placement": "pb" + }, + "prebid": { + "storedrequest": { + "id": "pb" + } + } + } + }, + { + "id": "imp-video", + "video": { + "mimes": ["video/mp4"] + }, + "ext": { + "bidder": { + "account": "multi-acct", + "placement": "pv" + }, + "prebid": { + "storedrequest": { + "id": "pv" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "multi-acct" + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["imp-banner", "imp-video"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "EUR", + "seatbid": [ + { + "seat": "s1", + "bid": [ + { + "id": "b1", + "impid": "imp-banner", + "price": 1.00, + "adm": "
banner
", + "w": 300, + "h": 250, + "crid": "c1" + }, + { + "id": "b2", + "impid": "imp-video", + "price": 2.00, + "adm": "", + "crid": "c2" + } + ] + }, + { + "seat": "s2", + "bid": [ + { + "id": "b3", + "impid": "imp-banner", + "price": 1.50, + "adm": "
banner2
", + "w": 300, + "h": 250, + "crid": "c3" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "b1", + "impid": "imp-banner", + "price": 1.00, + "adm": "
banner
", + "w": 300, + "h": 250, + "crid": "c1" + }, + "type": "banner" + }, + { + "bid": { + "id": "b2", + "impid": "imp-video", + "price": 2.00, + "adm": "", + "crid": "c2" + }, + "type": "video" + }, + { + "bid": { + "id": "b3", + "impid": "imp-banner", + "price": 1.50, + "adm": "
banner2
", + "w": 300, + "h": 250, + "crid": "c3" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/supplemental/no-response-body.json b/adapters/teal/tealtest/supplemental/no-response-body.json new file mode 100644 index 0000000000..203d5674b5 --- /dev/null +++ b/adapters/teal/tealtest/supplemental/no-response-body.json @@ -0,0 +1,119 @@ +{ + "mockBidRequest": { + "device": { + "dnt": 0, + "ip": "192.0.2.1", + "language": "en", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "id": "test-request-banner", + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + }, + "id": "test-imp-banner" + } + ], + "regs": { + "ext": { + "gdpr": 0 + } + }, + "site": { + "domain": "example.com", + "id": "demo-site", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + }, + "user": { + "id": "demo-user" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", + "ip": "192.0.2.1", + "language": "en", + "dnt": 0 + }, + "user": { + "id": "demo-user" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": [ + "test-imp-banner" + ] + }, + "mockResponse": { + "status": 200 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found", + "comparison": "startswith" + } + ] +} diff --git a/adapters/teal/tealtest/supplemental/no-site-no-app.json b/adapters/teal/tealtest/supplemental/no-site-no-app.json new file mode 100644 index 0000000000..051e8f026e --- /dev/null +++ b/adapters/teal/tealtest/supplemental/no-site-no-app.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": ["test-imp-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "bid-1", + "impid": "test-imp-banner", + "price": 1.50, + "adm": "
ad
", + "w": 300, + "h": 250, + "crid": "c1" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "test-imp-banner", + "price": 1.50, + "adm": "
ad
", + "w": 300, + "h": 250, + "crid": "c1" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/teal/tealtest/supplemental/status-204.json b/adapters/teal/tealtest/supplemental/status-204.json new file mode 100644 index 0000000000..22cdc1ad7d --- /dev/null +++ b/adapters/teal/tealtest/supplemental/status-204.json @@ -0,0 +1,114 @@ +{ + "mockBidRequest": { + "device": { + "dnt": 0, + "ip": "192.0.2.1", + "language": "en", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "id": "test-request-banner", + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + }, + "id": "test-imp-banner" + } + ], + "regs": { + "ext": { + "gdpr": 0 + } + }, + "site": { + "domain": "example.com", + "id": "demo-site", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + }, + "user": { + "id": "demo-user" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", + "ip": "192.0.2.1", + "language": "en", + "dnt": 0 + }, + "user": { + "id": "demo-user" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": [ + "test-imp-banner" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/teal/tealtest/supplemental/status-400.json b/adapters/teal/tealtest/supplemental/status-400.json new file mode 100644 index 0000000000..28b430674c --- /dev/null +++ b/adapters/teal/tealtest/supplemental/status-400.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "device": { + "dnt": 0, + "ip": "192.0.2.1", + "language": "en", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "id": "test-request-banner", + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + }, + "id": "test-imp-banner" + } + ], + "regs": { + "ext": { + "gdpr": 0 + } + }, + "site": { + "domain": "example.com", + "id": "demo-site", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + }, + "user": { + "id": "demo-user" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", + "ip": "192.0.2.1", + "language": "en", + "dnt": 0 + }, + "user": { + "id": "demo-user" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": [ + "test-imp-banner" + ] + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/teal/tealtest/supplemental/status-404.json b/adapters/teal/tealtest/supplemental/status-404.json new file mode 100644 index 0000000000..9e3c8f9a63 --- /dev/null +++ b/adapters/teal/tealtest/supplemental/status-404.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "device": { + "dnt": 0, + "ip": "192.0.2.1", + "language": "en", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + "id": "test-request-banner", + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + } + }, + "id": "test-imp-banner" + } + ], + "regs": { + "ext": { + "gdpr": 0 + } + }, + "site": { + "domain": "example.com", + "id": "demo-site", + "page": "https://example.com/demo", + "publisher": { + "id": "demo-publisher" + } + }, + "user": { + "id": "demo-user" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://test.example.com/bid", + "body": { + "id": "test-request-banner", + "imp": [ + { + "id": "test-imp-banner", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "account": "test-account", + "placement": "test-placement300x250" + }, + "prebid": { + "storedrequest": { + "id": "test-placement300x250" + } + } + } + } + ], + "site": { + "id": "demo-site", + "domain": "example.com", + "page": "https://example.com/demo", + "publisher": { + "id": "test-account" + } + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", + "ip": "192.0.2.1", + "language": "en", + "dnt": 0 + }, + "user": { + "id": "demo-user" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "ext": { + "bids": { + "pbs": 1 + } + } + }, + "impIDs": [ + "test-imp-banner" + ] + }, + "mockResponse": { + "status": 404, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/telaria/params_test.go b/adapters/telaria/params_test.go index 7b1dfe0854..1ed6d600ed 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/telaria/telaria.go b/adapters/telaria/telaria.go index 1805bfaea0..1969ed5a52 100644 --- a/adapters/telaria/telaria.go +++ b/adapters/telaria/telaria.go @@ -7,11 +7,11 @@ import ( "strconv" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const Endpoint = "https://ads.tremorhub.com/ad/rtb/prebid" diff --git a/adapters/telaria/telaria_test.go b/adapters/telaria/telaria_test.go index 8c55e7b900..73fbed3d08 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/teqblaze/params_test.go b/adapters/teqblaze/params_test.go index 2c86ea1485..ac99ad6657 100644 --- a/adapters/teqblaze/params_test.go +++ b/adapters/teqblaze/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/teqblaze/teqblaze.go b/adapters/teqblaze/teqblaze.go index b6e391bb85..203ca847c3 100644 --- a/adapters/teqblaze/teqblaze.go +++ b/adapters/teqblaze/teqblaze.go @@ -5,10 +5,10 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/teqblaze/teqblaze_test.go b/adapters/teqblaze/teqblaze_test.go index f4a3cdca92..22537c07e3 100644 --- a/adapters/teqblaze/teqblaze_test.go +++ b/adapters/teqblaze/teqblaze_test.go @@ -3,9 +3,9 @@ package teqblaze 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/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/theadx/params_test.go b/adapters/theadx/params_test.go index 09440b335c..764d5edc32 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 34b1e1a3b4..5460daa83a 100644 --- a/adapters/theadx/theadx.go +++ b/adapters/theadx/theadx.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/theadx/theadx_test.go b/adapters/theadx/theadx_test.go index a945bd15fe..170a3150d1 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/thetradedesk/params_test.go b/adapters/thetradedesk/params_test.go index b0829fb290..1cf105857c 100644 --- a/adapters/thetradedesk/params_test.go +++ b/adapters/thetradedesk/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/thetradedesk/thetradedesk.go b/adapters/thetradedesk/thetradedesk.go index f3d81d2a06..46c1cb0649 100644 --- a/adapters/thetradedesk/thetradedesk.go +++ b/adapters/thetradedesk/thetradedesk.go @@ -10,11 +10,11 @@ import ( "strings" "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/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) @@ -204,6 +204,8 @@ func getBidType(markupType openrtb2.MarkupType) (openrtb_ext.BidType, error) { return openrtb_ext.BidTypeVideo, nil case openrtb2.MarkupNative: return openrtb_ext.BidTypeNative, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil default: return "", fmt.Errorf("unsupported mtype: %d", markupType) } diff --git a/adapters/thetradedesk/thetradedesk_test.go b/adapters/thetradedesk/thetradedesk_test.go index dec4652ce7..c667850a6b 100644 --- a/adapters/thetradedesk/thetradedesk_test.go +++ b/adapters/thetradedesk/thetradedesk_test.go @@ -3,15 +3,15 @@ package thetradedesk import ( "encoding/json" "errors" - "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" "net/http" "testing" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -100,6 +100,14 @@ func TestGetBidType(t *testing.T) { expectedBidTypeId: openrtb_ext.BidTypeNative, wantErr: false, }, + { + name: "audio", + args: args{ + markupType: openrtb2.MarkupAudio, + }, + expectedBidTypeId: openrtb_ext.BidTypeAudio, + wantErr: false, + }, { name: "invalid", args: args{ diff --git a/adapters/thetradedesk/thetradedesktest/exemplary/simple-audio.json b/adapters/thetradedesk/thetradedesktest/exemplary/simple-audio.json new file mode 100644 index 0000000000..6de40fa579 --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/exemplary/simple-audio.json @@ -0,0 +1,109 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com" + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": ["audio/mp4"] + }, + "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" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "123456" + } + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": ["audio/mp4"] + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-audio", + "ext": { + "prebid": { + "type": "audio" + } + }, + "mtype": 3 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-audio", + "ext": { + "prebid": { + "type": "audio" + } + }, + "mtype": 3 + }, + "type": "audio" + } + ] + } + ] +} diff --git a/adapters/tpmn/params_test.go b/adapters/tpmn/params_test.go index 674da5fb65..a7159abc4e 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/tpmn/tpmn.go b/adapters/tpmn/tpmn.go index 262fc28ac6..95e2d03d35 100644 --- a/adapters/tpmn/tpmn.go +++ b/adapters/tpmn/tpmn.go @@ -7,10 +7,10 @@ import ( "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/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // TpmnAdapter struct diff --git a/adapters/tpmn/tpmn_test.go b/adapters/tpmn/tpmn_test.go index 865771e89c..f207467fb1 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/tradplus/params_test.go b/adapters/tradplus/params_test.go index aa92db4a2f..7a537e911e 100644 --- a/adapters/tradplus/params_test.go +++ b/adapters/tradplus/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -35,9 +35,13 @@ func TestInvalidParams(t *testing.T) { } var validParams = []string{ + `{"accountId": "11233"}`, `{"accountId": "11233", "zoneId": ""}`, - `{"accountId": "aaa", "zoneId": "us"}`, - `{"accountId": "aa", "accountId": "sin"}`, + `{"accountId": "11233", "zoneId": "host"}`, + `{"accountId": "aaa", "zoneId": "host.example.com"}`, + `{"accountId": "aa", "zoneId": "host-example.test"}`, + `{"accountId": "aaa", "zoneId": "Host.Example.com"}`, + `{"accountId": "aaa", "zoneId": "localhost"}`, } var invalidParams = []string{ @@ -50,4 +54,14 @@ var invalidParams = []string{ `{"accountId": null}`, `{"zoneId": "aaa"}`, `{"zoneId": null}`, + `{"accountId": "aaa", "zoneId": "/path"}`, + `{"accountId": "aaa", "zoneId": "//evil.com"}`, + `{"accountId": "aaa", "zoneId": "host/path"}`, + `{"accountId": "aaa", "zoneId": "host?query=1"}`, + `{"accountId": "aaa", "zoneId": "host#fragment"}`, + `{"accountId": "aaa", "zoneId": "user@host"}`, + `{"accountId": "aaa", "zoneId": "https://host.com"}`, + `{"accountId": "aaa", "zoneId": "host:notaport"}`, + `{"accountId": "aaa", "zoneId": "host:8080:extra"}`, + `{"accountId": "aaa", "zoneId": "host:8080"}`, } diff --git a/adapters/tradplus/tradplus.go b/adapters/tradplus/tradplus.go index 4800c73e84..4c1d08f404 100644 --- a/adapters/tradplus/tradplus.go +++ b/adapters/tradplus/tradplus.go @@ -7,12 +7,13 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/urlutil" ) type adapter struct { @@ -86,6 +87,9 @@ func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpTradPlus, error) { } func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtImpTradPlus) (string, error) { + if params.ZoneID != "" && !urlutil.IsSafeHost(params.ZoneID) { + return "", &errortypes.BadInput{Message: "Invalid ZoneID"} + } endpointParams := macros.EndpointTemplateParams{ AccountID: params.AccountID, ZoneID: params.ZoneID, diff --git a/adapters/tradplus/tradplus_test.go b/adapters/tradplus/tradplus_test.go index e081607f4e..38dc571e04 100644 --- a/adapters/tradplus/tradplus_test.go +++ b/adapters/tradplus/tradplus_test.go @@ -5,9 +5,9 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/tradplus/tradplustest/supplemental/invalid-zoneid.json b/adapters/tradplus/tradplustest/supplemental/invalid-zoneid.json new file mode 100644 index 0000000000..75ebc22bd5 --- /dev/null +++ b/adapters/tradplus/tradplustest/supplemental/invalid-zoneid.json @@ -0,0 +1,25 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "accountId": "testaccount", + "zoneId": "evil.com/path?redirect=http://attacker.com#" + } + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "Invalid ZoneID", + "comparison": "literal" + } + ] +} diff --git a/adapters/trafficgate/params_test.go b/adapters/trafficgate/params_test.go index 0667a8bc5a..0a0d34ea04 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // TestValidParams makes sure that the trafficgate schema accepts all imp.ext fields which we intend to support. @@ -36,7 +36,12 @@ func TestInvalidParams(t *testing.T) { } var validParams = []string{ - `{"placementId": "11", "host": "example"}`, + `{"placementId": "11", "host": "host"}`, + `{"placementId": "11", "host": "host.example.com"}`, + `{"placementId": "11", "host": "host.example.com:8080"}`, + `{"placementId": "11", "host": "host-example.test"}`, + `{"placementId": "11", "host": "Host.Example.com"}`, + `{"placementId": "11", "host": "localhost:3000"}`, } var invalidParams = []string{ @@ -45,4 +50,13 @@ var invalidParams = []string{ `{"placement_id": 346, "host": ""}`, `{"placementID": "", "HOST": "example"}`, `{"placementId": 234}`, + `{"placementId": "11", "host": "/path"}`, + `{"placementId": "11", "host": "//evil.com"}`, + `{"placementId": "11", "host": "host/path"}`, + `{"placementId": "11", "host": "host?query=1"}`, + `{"placementId": "11", "host": "host#fragment"}`, + `{"placementId": "11", "host": "user@host"}`, + `{"placementId": "11", "host": "https://host.com"}`, + `{"placementId": "11", "host": "host:notaport"}`, + `{"placementId": "11", "host": "host:8080:extra"}`, } diff --git a/adapters/trafficgate/trafficgate.go b/adapters/trafficgate/trafficgate.go index d4d181399d..741b70745f 100644 --- a/adapters/trafficgate/trafficgate.go +++ b/adapters/trafficgate/trafficgate.go @@ -7,12 +7,13 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/urlutil" ) type adapter struct { @@ -153,6 +154,9 @@ func getBidderParams(imp *openrtb2.Imp) (*openrtb_ext.ExtImpTrafficGate, error) Message: "Bidder parameters required", } } + if !urlutil.IsSafeHost(TrafficGateExt.Host) { + return nil, &errortypes.BadInput{Message: "Invalid Host"} + } return &TrafficGateExt, nil } diff --git a/adapters/trafficgate/trafficgate_test.go b/adapters/trafficgate/trafficgate_test.go index df932538d9..de5c0459cb 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/trafficgate/trafficgatetest/supplemental/invalid-host.json b/adapters/trafficgate/trafficgatetest/supplemental/invalid-host.json new file mode 100644 index 0000000000..fa4589e99d --- /dev/null +++ b/adapters/trafficgate/trafficgatetest/supplemental/invalid-host.json @@ -0,0 +1,35 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "1", + "host": "evil.com/path?redirect=http://attacker.com#" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.test.app" + } + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Invalid Host", + "comparison": "literal" + } + ] +} diff --git a/adapters/triplelift/triplelift.go b/adapters/triplelift/triplelift.go index c5d89cd250..fc5f4c641e 100644 --- a/adapters/triplelift/triplelift.go +++ b/adapters/triplelift/triplelift.go @@ -4,13 +4,14 @@ import ( "encoding/json" "fmt" "net/http" + "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type TripleliftAdapter struct { @@ -33,7 +34,7 @@ func getBidType(ext TripleliftRespExt) openrtb_ext.BidType { return openrtb_ext.BidTypeBanner } -func processImp(imp *openrtb2.Imp) error { +func processImp(imp *openrtb2.Imp, reqInfo *adapters.ExtraRequestInfo) error { // get the triplelift extension var ext adapters.ExtImpBidder var tlext openrtb_ext.ExtImpTriplelift @@ -48,15 +49,35 @@ func processImp(imp *openrtb2.Imp) error { } imp.TagID = tlext.InvCode // floor is optional - if tlext.Floor == nil { - return nil - } else { + if tlext.Floor != nil { imp.BidFloor = *tlext.Floor } + // Normalize bid floor to USD - TLX expects USD + if err := resolveBidFloorCurrency(imp, reqInfo); err != nil { + return err + } // no error return nil } +// Normalize imp.BidFloor to USD +func resolveBidFloorCurrency(imp *openrtb2.Imp, reqInfo *adapters.ExtraRequestInfo) error { + if imp.BidFloor <= 0 { + return nil + } + if imp.BidFloorCur != "" && strings.ToUpper(imp.BidFloorCur) != "USD" { + converted, err := reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD") + if err != nil { + return &errortypes.BadInput{ + Message: fmt.Sprintf("Unable to convert bid floor from %s to USD: %s", imp.BidFloorCur, err.Error()), + } + } + imp.BidFloor = converted + } + imp.BidFloorCur = "USD" + return nil +} + func (a *TripleliftAdapter) MakeRequests(request *openrtb2.BidRequest, extra *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { errs := make([]error, 0, len(request.Imp)+1) reqs := make([]*adapters.RequestData, 0, 1) @@ -66,7 +87,7 @@ func (a *TripleliftAdapter) MakeRequests(request *openrtb2.BidRequest, extra *ad var validImps []openrtb2.Imp // pre-process the imps for _, imp := range tlRequest.Imp { - if err := processImp(&imp); err == nil { + if err := processImp(&imp, extra); err == nil { validImps = append(validImps, imp) } else { errs = append(errs, err) @@ -126,6 +147,9 @@ func (a *TripleliftAdapter) MakeBids(internalRequest *openrtb2.BidRequest, exter count := getBidCount(bidResp) bidResponse := adapters.NewBidderResponseWithBidsCapacity(count) + // Bids are always denominated in USD + bidResponse.Currency = "USD" + for _, sb := range bidResp.SeatBid { for i := 0; i < len(sb.Bid); i++ { bid := sb.Bid[i] diff --git a/adapters/triplelift/triplelift_currency_test.go b/adapters/triplelift/triplelift_currency_test.go new file mode 100644 index 0000000000..76611bd35b --- /dev/null +++ b/adapters/triplelift/triplelift_currency_test.go @@ -0,0 +1,91 @@ +package triplelift + +import ( + "errors" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +type mockCurrencyConversion struct { + mock.Mock +} + +func (m *mockCurrencyConversion) GetRate(from, to string) (float64, error) { + args := m.Called(from, to) + return args.Get(0).(float64), args.Error(1) +} + +func (m *mockCurrencyConversion) GetRates() *map[string]map[string]float64 { + args := m.Called() + return args.Get(0).(*map[string]map[string]float64) +} + +var currencyTestCases = map[string]struct { + imp openrtb2.Imp + setMock func(m *mock.Mock) + expectedImp openrtb2.Imp + assertError assert.ErrorAssertionFunc +}{ + "no floor, no currency": { + imp: openrtb2.Imp{BidFloor: 0, BidFloorCur: ""}, + setMock: func(m *mock.Mock) {}, + expectedImp: openrtb2.Imp{BidFloor: 0, BidFloorCur: ""}, + assertError: assert.NoError, + }, + "floor, empty currency (implicit USD)": { + imp: openrtb2.Imp{BidFloor: 1.25, BidFloorCur: ""}, + setMock: func(m *mock.Mock) {}, + expectedImp: openrtb2.Imp{BidFloor: 1.25, BidFloorCur: "USD"}, + assertError: assert.NoError, + }, + "USD floor, no conversion needed": { + imp: openrtb2.Imp{BidFloor: 2.0, BidFloorCur: "USD"}, + setMock: func(m *mock.Mock) {}, + expectedImp: openrtb2.Imp{BidFloor: 2.0, BidFloorCur: "USD"}, + assertError: assert.NoError, + }, + "usd lowercase - no conversion needed": { + imp: openrtb2.Imp{BidFloor: 2.0, BidFloorCur: "usd"}, + setMock: func(m *mock.Mock) {}, + expectedImp: openrtb2.Imp{BidFloor: 2.0, BidFloorCur: "USD"}, + assertError: assert.NoError, + }, + "EUR floor converts to USD": { + imp: openrtb2.Imp{BidFloor: 1.0, BidFloorCur: "EUR"}, + setMock: func(m *mock.Mock) { + m.On("GetRate", "EUR", "USD").Return(1.1, nil) + }, + expectedImp: openrtb2.Imp{BidFloor: 1.1, BidFloorCur: "USD"}, + assertError: assert.NoError, + }, + "unknown currency returns error": { + imp: openrtb2.Imp{BidFloor: 1.0, BidFloorCur: "ABC"}, + setMock: func(m *mock.Mock) { + m.On("GetRate", "ABC", "USD").Return(0.0, errors.New("conversion rate not found")) + }, + expectedImp: openrtb2.Imp{BidFloor: 1.0, BidFloorCur: "ABC"}, + assertError: assert.Error, + }, +} + +func TestResolveBidFloorCurrency(t *testing.T) { + for name, tc := range currencyTestCases { + t.Run(name, func(t *testing.T) { + imp := tc.imp + mockConversions := &mockCurrencyConversion{} + tc.setMock(&mockConversions.Mock) + + reqInfo := adapters.ExtraRequestInfo{CurrencyConversions: mockConversions} + err := resolveBidFloorCurrency(&imp, &reqInfo) + + tc.assertError(t, err) + assert.Equal(t, tc.expectedImp.BidFloor, imp.BidFloor) + assert.Equal(t, tc.expectedImp.BidFloorCur, imp.BidFloorCur) + mockConversions.AssertExpectations(t) + }) + } +} diff --git a/adapters/triplelift/triplelift_test.go b/adapters/triplelift/triplelift_test.go index 1fd5fc8d55..547c8609bb 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/triplelift/triplelifttest/exemplary/optional-params.json b/adapters/triplelift/triplelifttest/exemplary/optional-params.json index 33da6cb296..52e253ee37 100644 --- a/adapters/triplelift/triplelifttest/exemplary/optional-params.json +++ b/adapters/triplelift/triplelifttest/exemplary/optional-params.json @@ -48,6 +48,7 @@ }, "tagid": "foo", "bidfloor": 20, + "bidfloorcur": "USD", "ext": { "bidder": { "inventoryCode": "foo", diff --git a/adapters/triplelift/triplelifttest/exemplary/simple-banner-eur-floor.json b/adapters/triplelift/triplelifttest/exemplary/simple-banner-eur-floor.json new file mode 100644 index 0000000000..0415711292 --- /dev/null +++ b/adapters/triplelift/triplelifttest/exemplary/simple-banner-eur-floor.json @@ -0,0 +1,83 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "cur": ["USD"], + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{ "w": 300, "h": 250 }] + }, + "bidfloor": 1.0, + "bidfloorcur": "EUR", + "ext": { + "bidder": { "inventoryCode": "aa" } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { "EUR": { "USD": 1.1 } }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://tlx.3lift.net/s2s/auction?sra=1&supplier_id=20", + "body": { + "id": "test-request-id", + "cur": ["USD"], + "imp": [ + { + "id": "test-imp-id", + "banner": { "format": [{ "w": 300, "h": 250 }] }, + "bidfloor": 1.1, + "bidfloorcur": "USD", + "tagid": "aa", + "ext": { "bidder": { "inventoryCode": "aa" } } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { "EUR": { "USD": 1.1 } }, + "usepbsrates": false + } + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "958", + "bid": [{ + "id": "b1", "impid": "test-imp-id", "price": 1.5, + "adm": "some-ad", "crid": "cr1", "w": 300, "h": 250, + "ext": { "triplelift_pb": { "format": 2 } } + }] + }], + "bidid": "auction-id" + } + } + } + ], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "b1", "impid": "test-imp-id", "price": 1.5, + "adm": "some-ad", "crid": "cr1", "w": 300, "h": 250, + "ext": { "triplelift_pb": { "format": 2 } } + }, + "type": "banner" + }] + }] +} diff --git a/adapters/triplelift/triplelifttest/exemplary/simple-video.json b/adapters/triplelift/triplelifttest/exemplary/simple-video.json index 8d63b9acf3..66f9eac6c5 100644 --- a/adapters/triplelift/triplelifttest/exemplary/simple-video.json +++ b/adapters/triplelift/triplelifttest/exemplary/simple-video.json @@ -40,6 +40,7 @@ { "tagid": "aaw", "bidfloor": 0.10, + "bidfloorcur": "USD", "id": "test-imp-id", "video": { "mimes": [ diff --git a/adapters/triplelift/triplelifttest/supplemental/video-format-11.json b/adapters/triplelift/triplelifttest/supplemental/video-format-11.json index 372cc51ea0..a1c631bf35 100644 --- a/adapters/triplelift/triplelifttest/supplemental/video-format-11.json +++ b/adapters/triplelift/triplelifttest/supplemental/video-format-11.json @@ -31,6 +31,7 @@ { "tagid": "aaw", "bidfloor": 0.10, + "bidfloorcur": "USD", "id": "test-imp-id", "video": { "mimes": [ "video/mp4"], diff --git a/adapters/triplelift/triplelifttest/supplemental/video-format-12.json b/adapters/triplelift/triplelifttest/supplemental/video-format-12.json index f2b55a0401..026dabbb14 100644 --- a/adapters/triplelift/triplelifttest/supplemental/video-format-12.json +++ b/adapters/triplelift/triplelifttest/supplemental/video-format-12.json @@ -31,6 +31,7 @@ { "tagid": "aaw", "bidfloor": 0.10, + "bidfloorcur": "USD", "id": "test-imp-id", "video": { "mimes": [ "video/mp4"], diff --git a/adapters/triplelift/triplelifttest/supplemental/video-format-17.json b/adapters/triplelift/triplelifttest/supplemental/video-format-17.json index 26dcc943af..f4a591cf40 100644 --- a/adapters/triplelift/triplelifttest/supplemental/video-format-17.json +++ b/adapters/triplelift/triplelifttest/supplemental/video-format-17.json @@ -31,6 +31,7 @@ { "tagid": "aaw", "bidfloor": 0.10, + "bidfloorcur": "USD", "id": "test-imp-id", "video": { "mimes": [ "video/mp4"], diff --git a/adapters/triplelift_native/params_test.go b/adapters/triplelift_native/params_test.go index 743c3d87ed..1b65fc46fc 100644 --- a/adapters/triplelift_native/params_test.go +++ b/adapters/triplelift_native/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/triplelift_native/triplelift_native.go b/adapters/triplelift_native/triplelift_native.go index 1d4c6bf638..1e102f0d2d 100644 --- a/adapters/triplelift_native/triplelift_native.go +++ b/adapters/triplelift_native/triplelift_native.go @@ -4,13 +4,14 @@ import ( "encoding/json" "fmt" "net/http" + "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type TripleliftNativeAdapter struct { @@ -47,7 +48,7 @@ func getBidType(ext TripleliftRespExt) openrtb_ext.BidType { return openrtb_ext.BidTypeNative } -func processImp(imp *openrtb2.Imp, request *openrtb2.BidRequest) error { +func processImp(imp *openrtb2.Imp, request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) error { // get the triplelift extension var ext ExtImp var tlext openrtb_ext.ExtImpTriplelift @@ -69,14 +70,36 @@ func processImp(imp *openrtb2.Imp, request *openrtb2.BidRequest) error { } // floor is optional - if tlext.Floor == nil { - return nil + if tlext.Floor != nil { + imp.BidFloor = *tlext.Floor + } + + // Normalize bid floor to USD + if err := resolveBidFloorCurrency(imp, reqInfo); err != nil { + return err } - imp.BidFloor = *tlext.Floor return nil } +// Normalize imp.BidFloor to USD +func resolveBidFloorCurrency(imp *openrtb2.Imp, reqInfo *adapters.ExtraRequestInfo) error { + if imp.BidFloor <= 0 { + return nil + } + if imp.BidFloorCur != "" && strings.ToUpper(imp.BidFloorCur) != "USD" { + converted, err := reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD") + if err != nil { + return &errortypes.BadInput{ + Message: fmt.Sprintf("Unable to convert bid floor from %s to USD: %s", imp.BidFloorCur, err.Error()), + } + } + imp.BidFloor = converted + } + imp.BidFloorCur = "USD" + 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" @@ -113,7 +136,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, request); err == nil { + if err := processImp(&imp, request, extra); err == nil { validImps = append(validImps, imp) } else { errs = append(errs, err) @@ -186,6 +209,9 @@ func (a *TripleliftNativeAdapter) MakeBids(internalRequest *openrtb2.BidRequest, count := getBidCount(bidResp) bidResponse := adapters.NewBidderResponseWithBidsCapacity(count) + // Bids are always denominated in USD + bidResponse.Currency = "USD" + for _, sb := range bidResp.SeatBid { for i := 0; i < len(sb.Bid); i++ { bid := sb.Bid[i] diff --git a/adapters/triplelift_native/triplelift_native_currency_test.go b/adapters/triplelift_native/triplelift_native_currency_test.go new file mode 100644 index 0000000000..8a194bc9b1 --- /dev/null +++ b/adapters/triplelift_native/triplelift_native_currency_test.go @@ -0,0 +1,76 @@ +package triplelift_native + +import ( + "errors" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +type mockCurrencyConversion struct { + mock.Mock +} + +func (m *mockCurrencyConversion) GetRate(from, to string) (float64, error) { + args := m.Called(from, to) + return args.Get(0).(float64), args.Error(1) +} + +func (m *mockCurrencyConversion) GetRates() *map[string]map[string]float64 { + args := m.Called() + return args.Get(0).(*map[string]map[string]float64) +} + +func TestResolveBidFloorCurrency(t *testing.T) { + cases := map[string]struct { + imp openrtb2.Imp + setMock func(m *mock.Mock) + expectedImp openrtb2.Imp + assertError assert.ErrorAssertionFunc + }{ + "no floor": { + imp: openrtb2.Imp{BidFloor: 0, BidFloorCur: "EUR"}, + setMock: func(m *mock.Mock) {}, + expectedImp: openrtb2.Imp{BidFloor: 0, BidFloorCur: "EUR"}, + assertError: assert.NoError, + }, + "USD floor passthrough": { + imp: openrtb2.Imp{BidFloor: 3.0, BidFloorCur: "USD"}, + setMock: func(m *mock.Mock) {}, + expectedImp: openrtb2.Imp{BidFloor: 3.0, BidFloorCur: "USD"}, + assertError: assert.NoError, + }, + "EUR converts to USD": { + imp: openrtb2.Imp{BidFloor: 2.0, BidFloorCur: "EUR"}, + setMock: func(m *mock.Mock) { + m.On("GetRate", "EUR", "USD").Return(1.08, nil) + }, + expectedImp: openrtb2.Imp{BidFloor: 2.16, BidFloorCur: "USD"}, + assertError: assert.NoError, + }, + "conversion error": { + imp: openrtb2.Imp{BidFloor: 1.0, BidFloorCur: "XYZ"}, + setMock: func(m *mock.Mock) { + m.On("GetRate", "XYZ", "USD").Return(0.0, errors.New("rate not found")) + }, + expectedImp: openrtb2.Imp{BidFloor: 1.0, BidFloorCur: "XYZ"}, + assertError: assert.Error, + }, + } + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + imp := tc.imp + m := &mockCurrencyConversion{} + tc.setMock(&m.Mock) + reqInfo := adapters.ExtraRequestInfo{CurrencyConversions: m} + err := resolveBidFloorCurrency(&imp, &reqInfo) + tc.assertError(t, err) + assert.Equal(t, tc.expectedImp.BidFloor, imp.BidFloor) + assert.Equal(t, tc.expectedImp.BidFloorCur, imp.BidFloorCur) + m.AssertExpectations(t) + }) + } +} diff --git a/adapters/triplelift_native/triplelift_native_test.go b/adapters/triplelift_native/triplelift_native_test.go index 651890b01e..e3f3b7958c 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/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 index 6950942f19..e6a91ded53 100644 --- 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 @@ -36,6 +36,7 @@ }, "tagid": "invcode", "bidfloor": 20, + "bidfloorcur": "USD", "ext": { "bidder": { "inventoryCode": "invcode", diff --git a/adapters/triplelift_native/triplelift_nativetest/exemplary/app-msn.json b/adapters/triplelift_native/triplelift_nativetest/exemplary/app-msn.json index 420cab5aff..570456c8bb 100644 --- a/adapters/triplelift_native/triplelift_nativetest/exemplary/app-msn.json +++ b/adapters/triplelift_native/triplelift_nativetest/exemplary/app-msn.json @@ -36,6 +36,7 @@ }, "tagid": "bar", "bidfloor": 20, + "bidfloorcur": "USD", "ext": { "bidder": { "inventoryCode": "invcode", diff --git a/adapters/triplelift_native/triplelift_nativetest/exemplary/app.json b/adapters/triplelift_native/triplelift_nativetest/exemplary/app.json index d1cd72947b..c6a36ee0af 100644 --- a/adapters/triplelift_native/triplelift_nativetest/exemplary/app.json +++ b/adapters/triplelift_native/triplelift_nativetest/exemplary/app.json @@ -36,6 +36,7 @@ }, "tagid": "invcode", "bidfloor": 20, + "bidfloorcur": "USD", "ext": { "bidder": { "inventoryCode": "invcode", 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 index 48162742a1..8ad19e9eef 100644 --- 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 @@ -36,6 +36,7 @@ }, "tagid": "invcode", "bidfloor": 20, + "bidfloorcur": "USD", "ext": { "bidder": { "inventoryCode": "invcode", diff --git a/adapters/triplelift_native/triplelift_nativetest/exemplary/site-msn.json b/adapters/triplelift_native/triplelift_nativetest/exemplary/site-msn.json index 5aaa5a1ddc..dbb1091f4f 100644 --- a/adapters/triplelift_native/triplelift_nativetest/exemplary/site-msn.json +++ b/adapters/triplelift_native/triplelift_nativetest/exemplary/site-msn.json @@ -36,6 +36,7 @@ }, "tagid": "bar", "bidfloor": 20, + "bidfloorcur": "USD", "ext": { "bidder": { "inventoryCode": "invcode", diff --git a/adapters/triplelift_native/triplelift_nativetest/exemplary/site.json b/adapters/triplelift_native/triplelift_nativetest/exemplary/site.json index d273f4d411..a281ab34e4 100644 --- a/adapters/triplelift_native/triplelift_nativetest/exemplary/site.json +++ b/adapters/triplelift_native/triplelift_nativetest/exemplary/site.json @@ -36,6 +36,7 @@ }, "tagid": "invcode", "bidfloor": 20, + "bidfloorcur": "USD", "ext": { "bidder": { "inventoryCode": "invcode", 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 index ac119354c3..65e5cfe6df 100644 --- a/adapters/triplelift_native/triplelift_nativetest/supplemental/app-publisher-no-domain.json +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/app-publisher-no-domain.json @@ -34,6 +34,7 @@ }, "tagid": "invcode", "bidfloor": 20, + "bidfloorcur": "USD", "ext": { "bidder": { "inventoryCode": "invcode", diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/effective-publisher-allowed.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/effective-publisher-allowed.json index 74ac929478..c5d3337d1a 100644 --- a/adapters/triplelift_native/triplelift_nativetest/supplemental/effective-publisher-allowed.json +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/effective-publisher-allowed.json @@ -41,6 +41,7 @@ }, "tagid": "invcode", "bidfloor": 20, + "bidfloorcur": "USD", "ext": { "bidder": { "inventoryCode": "invcode", 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 index d44ae442fa..2e3a4d0fa5 100644 --- a/adapters/triplelift_native/triplelift_nativetest/supplemental/site-publisher-no-domain.json +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/site-publisher-no-domain.json @@ -35,6 +35,7 @@ }, "tagid": "invcode", "bidfloor": 20, + "bidfloorcur": "USD", "ext": { "bidder": { "inventoryCode": "invcode", diff --git a/adapters/trustedstack/params_test.go b/adapters/trustedstack/params_test.go index a38e0bb722..dee7427456 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 7c2fd4df50..0d795620cd 100644 --- a/adapters/trustedstack/trustedstack.go +++ b/adapters/trustedstack/trustedstack.go @@ -7,10 +7,10 @@ import ( "net/url" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/trustedstack/trustedstack_test.go b/adapters/trustedstack/trustedstack_test.go index d12202802e..223c97b974 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/trustx/params_test.go b/adapters/trustx/params_test.go new file mode 100644 index 0000000000..6c785e4174 --- /dev/null +++ b/adapters/trustx/params_test.go @@ -0,0 +1,51 @@ +package trustx + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/require" +) + +// This file actually intends to test static/bidder-params/trustx.json +// +// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.trustx + +// TestValidParams makes sure that the trustx schema accepts all imp.ext fields which we intend to support. +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + require.NoError(t, err, "Failed to fetch the json-schemas") + + for _, validParam := range validParams { + err := validator.Validate(openrtb_ext.BidderTrustX, json.RawMessage(validParam)) + require.NoError(t, err, "Schema rejected trustx params: %s", validParam) + } +} + +// TestInvalidParams makes sure that the trustx schema rejects all the imp.ext fields we don't support. +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + require.NoError(t, err, "Failed to fetch the json-schemas") + + for _, invalidParam := range invalidParams { + err := validator.Validate(openrtb_ext.BidderTrustX, json.RawMessage(invalidParam)) + require.Error(t, err, "Schema allowed unexpected params: %s", invalidParam) + } +} + +var validParams = []string{ + `{}`, + `{"uid": 1234}`, + `{"uid": 1234, "keywords":{"site": {}, "user": {}}}`, +} +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{"uid": "invalid_type"}`, + `{"keywords": "invalid_type"}`, +} diff --git a/adapters/trustx/trustx.go b/adapters/trustx/trustx.go new file mode 100644 index 0000000000..a36a1985f6 --- /dev/null +++ b/adapters/trustx/trustx.go @@ -0,0 +1,216 @@ +package trustx + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +type impExt struct { + Prebid *openrtb_ext.ExtImpPrebid `json:"prebid,omitempty"` + Bidder json.RawMessage `json:"bidder"` + Data *impExtData `json:"data,omitempty"` + Gpid string `json:"gpid,omitempty"` +} + +type impExtData struct { + PbAdslot string `json:"pbadslot,omitempty"` + AdServer *impExtDataAdServer `json:"adserver,omitempty"` +} + +type impExtDataAdServer struct { + Name string `json:"name,omitempty"` + AdSlot string `json:"adslot,omitempty"` +} + +type bidExt struct { + Bidder bidExtBidder `json:"bidder,omitempty"` +} + +type bidExtBidder struct { + TrustX bidExtBidderTrustX `json:"trustx,omitempty"` +} + +type bidExtBidderTrustX struct { + NetworkName string `json:"networkName,omitempty"` +} + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the TRUSTX 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, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var errs []error + for i := range request.Imp { + err := setImpExtData(&request.Imp[i]) + if err != nil { + errs = append(errs, err) + return nil, errs + } + } + + body, err := jsonutil.Marshal(request) + if err != nil { + errs = append(errs, err) + return nil, errs + } + + reqs := make([]*adapters.RequestData, 0, 1) + requestData := &adapters.RequestData{ + Method: http.MethodPost, + Uri: a.endpoint, + Body: body, + Headers: getHeaders(request), + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + } + reqs = append(reqs, requestData) + + return reqs, errs +} + +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 resp openrtb2.BidResponse + if err := jsonutil.Unmarshal(response.Body, &resp); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Bad Server Response", + }} + } + + var bidErrors []error + bidderResponse := adapters.NewBidderResponseWithBidsCapacity(1) + for i := range resp.SeatBid { + seatBid := &resp.SeatBid[i] + for j := range seatBid.Bid { + bid := &seatBid.Bid[j] + typedBid, err := getTypedBid(bid) + if err != nil { + bidErrors = append(bidErrors, err) + continue + } + bidderResponse.Bids = append(bidderResponse.Bids, typedBid) + } + } + + return bidderResponse, bidErrors +} + +func setImpExtData(imp *openrtb2.Imp) error { + var ext impExt + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { + //if unmarshalling fails, proceed with the request + return nil + } + if ext.Data != nil && ext.Data.AdServer != nil && ext.Data.AdServer.AdSlot != "" { + ext.Gpid = ext.Data.AdServer.AdSlot + extJSON, err := jsonutil.Marshal(ext) + if err != nil { + return err + } + imp.Ext = extJSON + } + return nil +} + +func getHeaders(request *openrtb2.BidRequest) http.Header { + headers := http.Header{} + headers.Set("Content-Type", "application/json;charset=utf-8") + headers.Set("Accept", "application/json") + headers.Set("X-Openrtb-Version", "2.6") + + if request.Site != nil { + if request.Site.Ref != "" { + headers.Set("Referer", request.Site.Ref) + } + if request.Site.Domain != "" { + headers.Set("Origin", request.Site.Domain) + } + } + + if request.Device != nil { + if len(request.Device.IP) > 0 { + headers.Set("X-Forwarded-For", request.Device.IP) + } + + if len(request.Device.IPv6) > 0 { + headers.Set("X-Forwarded-For", request.Device.IPv6) + } + + if len(request.Device.UA) > 0 { + headers.Set("User-Agent", request.Device.UA) + } + } + + return headers +} + +func getTypedBid(bid *openrtb2.Bid) (*adapters.TypedBid, error) { + var bidType openrtb_ext.BidType + switch bid.MType { + case openrtb2.MarkupBanner: + bidType = openrtb_ext.BidTypeBanner + case openrtb2.MarkupVideo: + bidType = openrtb_ext.BidTypeVideo + default: + return nil, &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unsupported MType: %v", bid.MType), + } + } + + var extBidPrebidVideo *openrtb_ext.ExtBidPrebidVideo + if bidType == openrtb_ext.BidTypeVideo { + extBidPrebidVideo = &openrtb_ext.ExtBidPrebidVideo{} + if len(bid.Cat) > 0 { + extBidPrebidVideo.PrimaryCategory = bid.Cat[0] + } + if bid.Dur > 0 { + extBidPrebidVideo.Duration = int(bid.Dur) + } + } + return &adapters.TypedBid{ + Bid: bid, + BidType: bidType, + BidVideo: extBidPrebidVideo, + BidMeta: getBidMeta(bid.Ext), + }, nil +} + +func getBidMeta(ext json.RawMessage) *openrtb_ext.ExtBidPrebidMeta { + if ext == nil { + return nil + } + var be bidExt + + if err := jsonutil.Unmarshal(ext, &be); err != nil { + return nil + } + var bidMeta *openrtb_ext.ExtBidPrebidMeta + if be.Bidder.TrustX.NetworkName != "" { + bidMeta = &openrtb_ext.ExtBidPrebidMeta{ + NetworkName: be.Bidder.TrustX.NetworkName, + } + } + return bidMeta +} diff --git a/adapters/trustx/trustx_test.go b/adapters/trustx/trustx_test.go new file mode 100644 index 0000000000..f3fe9d45e1 --- /dev/null +++ b/adapters/trustx/trustx_test.go @@ -0,0 +1,18 @@ +package trustx + +import ( + "testing" + + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/stretchr/testify/require" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderTrustX, config.Adapter{ + Endpoint: "https://test.localhost.com"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + require.NoError(t, buildErr, "Builder returned unexpected error") + adapterstest.RunJSONBidderTest(t, "trustxtest", bidder) +} diff --git a/adapters/trustx/trustxtest/exemplary/multiple-imp-types.json b/adapters/trustx/trustxtest/exemplary/multiple-imp-types.json new file mode 100644 index 0000000000..6e0f3511ee --- /dev/null +++ b/adapters/trustx/trustxtest/exemplary/multiple-imp-types.json @@ -0,0 +1,190 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + }, + { + "id": "test-imp-2", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "site": { + "domain": "test-domain.com", + "page": "http://test-domain.com/index" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "uri": "https://test.localhost.com", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Origin": [ + "test-domain.com" + ], + "X-Openrtb-Version": [ + "2.6" + ], + "User-Agent": [ + "ua" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "body": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + }, + { + "id": "test-imp-2", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "device": { + "ip": "123.123.123.123", + "ua": "ua" + }, + "site": { + "domain": "test-domain.com", + "page": "http://test-domain.com/index" + } + }, + "impIDs": [ + "test-imp", + "test-imp-2" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "impid": "test-imp", + "price": 10, + "adm": "test-ad", + "w": 1920, + "h": 1080, + "mtype": 2, + "dur": 15, + "cat": [ + "IAB3-8" + ] + }, + { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d708", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d223", + "price": 10, + "impid": "test-imp-2", + "adm": "", + "mtype": 1 + } + ], + "seat": "trustx" + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "impid": "test-imp", + "price": 10, + "adm": "test-ad", + "w": 1920, + "h": 1080, + "mtype": 2, + "dur": 15, + "cat": [ + "IAB3-8" + ] + }, + "type": "video", + "video": { + "duration": 15, + "primary_category": "IAB3-8" + } + }, + { + "bid": { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d708", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d223", + "price": 10, + "impid": "test-imp-2", + "adm": "", + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/trustx/trustxtest/exemplary/simple-app-banner.json b/adapters/trustx/trustxtest/exemplary/simple-app-banner.json new file mode 100644 index 0000000000..14351d090d --- /dev/null +++ b/adapters/trustx/trustxtest/exemplary/simple-app-banner.json @@ -0,0 +1,146 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "data": { + "adserver": { + "adslot": "test_ad_slot" + } + }, + "bidder": { + "uid": 1234 + } + } + } + ], + "app": { + "bundle": "app-bundle" + }, + "device": { + "ua": "ua", + "ip": "123.123.123.123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ], + "User-Agent": [ + "ua" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "https://test.localhost.com", + "body": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "gpid": "test_ad_slot", + "data": { + "adserver": { + "adslot": "test_ad_slot" + } + }, + "bidder": { + "uid": 1234 + } + } + } + ], + "device": { + "ua": "ua", + "ip": "123.123.123.123" + }, + "app": { + "bundle": "app-bundle" + } + }, + "impIDs": [ + "test-imp" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "price": 10, + "impid": "test-imp", + "adm": "", + "mtype": 1, + "ext": { + "bidder": { + "trustx": { + "networkName": "test-network" + } + } + } + } + ] + } + ], + "seat": "trustx" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "price": 10, + "impid": "test-imp", + "adm": "", + "mtype": 1, + "ext": { + "bidder": { + "trustx": { + "networkName": "test-network" + } + } + } + }, + "meta": { + "networkName": "test-network" + }, + "type": "banner" + } + ], + "seat": "trustx" + } + ] +} diff --git a/adapters/trustx/trustxtest/exemplary/simple-app-video.json b/adapters/trustx/trustxtest/exemplary/simple-app-video.json new file mode 100644 index 0000000000..5bd5deee4c --- /dev/null +++ b/adapters/trustx/trustxtest/exemplary/simple-app-video.json @@ -0,0 +1,141 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "app": { + "bundle": "app-bundle" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "uri": "https://test.localhost.com", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ], + "User-Agent": [ + "ua" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "body": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "app": { + "bundle": "app-bundle" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" + } + }, + "impIDs": [ + "test-imp" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "impid": "test-imp", + "price": 10, + "adm": "test-ad", + "w": 1920, + "h": 1080, + "mtype": 2, + "dur": 15, + "cat": [ + "IAB3-8" + ] + } + ], + "seat": "trustx" + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "impid": "test-imp", + "price": 10, + "adm": "test-ad", + "w": 1920, + "h": 1080, + "mtype": 2, + "dur": 15, + "cat": [ + "IAB3-8" + ] + }, + "type": "video", + "video": { + "duration": 15, + "primary_category": "IAB3-8" + } + } + ] + } + ] +} + diff --git a/adapters/trustx/trustxtest/exemplary/simple-web-banner.json b/adapters/trustx/trustxtest/exemplary/simple-web-banner.json new file mode 100644 index 0000000000..5771a229b9 --- /dev/null +++ b/adapters/trustx/trustxtest/exemplary/simple-web-banner.json @@ -0,0 +1,128 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "site": { + "domain": "test-domain.com", + "page": "http://test-domain.com/index", + "ref": "https://example.com/page" + }, + "device": { + "ua": "ua", + "ipv6": "2001:0db8:85a3:0000:0000:8a2e:0370:7334" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Origin": [ + "test-domain.com" + ], + "X-Openrtb-Version": [ + "2.6" + ], + "User-Agent": [ + "ua" + ], + "X-Forwarded-For": [ + "2001:0db8:85a3:0000:0000:8a2e:0370:7334" + ], + "Referer": [ + "https://example.com/page" + ] + }, + "uri": "https://test.localhost.com", + "body": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "site": { + "domain": "test-domain.com", + "page": "http://test-domain.com/index", + "ref": "https://example.com/page" + }, + "device": { + "ua": "ua", + "ipv6": "2001:0db8:85a3:0000:0000:8a2e:0370:7334" + } + }, + "impIDs": [ + "test-imp" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "price": 10, + "impid": "test-imp", + "adm": "", + "mtype": 1 + } + ] + } + ], + "seat": "trustx" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "price": 10, + "impid": "test-imp", + "adm": "", + "mtype": 1 + }, + "type": "banner" + } + ], + "seat": "trustx" + } + ] +} diff --git a/adapters/trustx/trustxtest/exemplary/simple-web-video.json b/adapters/trustx/trustxtest/exemplary/simple-web-video.json new file mode 100644 index 0000000000..aee0c04e99 --- /dev/null +++ b/adapters/trustx/trustxtest/exemplary/simple-web-video.json @@ -0,0 +1,146 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "site": { + "domain": "test-domain.com", + "page": "http://test-domain.com/index" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "uri": "https://test.localhost.com", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Origin": [ + "test-domain.com" + ], + "X-Openrtb-Version": [ + "2.6" + ], + "User-Agent": [ + "ua" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "body": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "site": { + "domain": "test-domain.com", + "page": "http://test-domain.com/index" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" + } + }, + "impIDs": [ + "test-imp" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "impid": "test-imp", + "price": 10, + "adm": "test-ad", + "w": 1920, + "h": 1080, + "mtype": 2, + "dur": 15, + "cat": [ + "IAB3-8" + ] + } + ], + "seat": "trustx" + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "impid": "test-imp", + "price": 10, + "adm": "test-ad", + "w": 1920, + "h": 1080, + "mtype": 2, + "dur": 15, + "cat": [ + "IAB3-8" + ] + }, + "type": "video", + "video": { + "duration": 15, + "primary_category": "IAB3-8" + } + } + ] + } + ] +} + diff --git a/adapters/trustx/trustxtest/supplemental/bad-server-response.json b/adapters/trustx/trustxtest/supplemental/bad-server-response.json new file mode 100644 index 0000000000..7f5221585c --- /dev/null +++ b/adapters/trustx/trustxtest/supplemental/bad-server-response.json @@ -0,0 +1,95 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "app": { + "bundle": "app-bundle" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "uri": "https://test.localhost.com", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ], + "User-Agent": [ + "ua" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "body": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "app": { + "bundle": "app-bundle" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" + } + }, + "impIDs": [ + "test-imp" + ] + }, + "mockResponse": { + "status": 200, + "body": "invalid response" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad Server Response", + "comparison": "literal" + } + ] +} + diff --git a/adapters/dxkulture/dxkulturetest/supplemental/status-code-bad-request.json b/adapters/trustx/trustxtest/supplemental/bad-status-400.json similarity index 53% rename from adapters/dxkulture/dxkulturetest/supplemental/status-code-bad-request.json rename to adapters/trustx/trustxtest/supplemental/bad-status-400.json index f152bb9ecf..0786d48891 100644 --- a/adapters/dxkulture/dxkulturetest/supplemental/status-code-bad-request.json +++ b/adapters/trustx/trustxtest/supplemental/bad-status-400.json @@ -1,103 +1,88 @@ { "mockBidRequest": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, + "id": "test-request", "imp": [ { - "id": "test-imp-id", + "id": "test-imp", "video": { "w": 1920, "h": 1080, "mimes": [ - "video/x-flv", "video/mp4" ] }, "ext": { "bidder": { - "publisherId": "pub123", - "placementId": "placement123" + "uid": 1234 } } } ], "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" + "domain": "test-domain.com", + "page": "http://test-domain.org/index" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" } }, "httpCalls": [ { "expectedRequest": { - "method": "GET", + "method": "POST", "headers": { - "Referer": [ - "http://site.com/ref" - ], - "Origin": [ - "site.com" - ], "Accept": [ "application/json" ], "Content-Type": [ "application/json;charset=utf-8" ], + "Origin": [ + "test-domain.com" + ], + "X-Openrtb-Version": [ + "2.6" + ], "User-Agent": [ - "user-agent" + "ua" ], "X-Forwarded-For": [ - "1.2.3.4" - ], - "X-Openrtb-Version": [ - "2.5" + "123.123.123.123" ] }, - "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", + "uri": "https://test.localhost.com", "body": { - "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, + "id": "test-request", "imp": [ { - "id": "test-imp-id", + "id": "test-imp", "video": { "w": 1920, "h": 1080, "mimes": [ - "video/x-flv", "video/mp4" ] }, "ext": { "bidder": { - "publisherId": "pub123", - "placementId": "placement123" + "uid": 1234 } } } ], "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" + "domain": "test-domain.com", + "page": "http://test-domain.org/index" + }, + "device": { + "ua": "ua", + "ip": "123.123.123.123" } }, - "impIDs":["test-imp-id"] + "impIDs": [ + "test-imp" + ] }, "mockResponse": { "status": 400 diff --git a/adapters/dxkulture/dxkulturetest/supplemental/status-code-other-error.json b/adapters/trustx/trustxtest/supplemental/bad-status-500.json similarity index 50% rename from adapters/dxkulture/dxkulturetest/supplemental/status-code-other-error.json rename to adapters/trustx/trustxtest/supplemental/bad-status-500.json index a568c3910b..53e49da220 100644 --- a/adapters/dxkulture/dxkulturetest/supplemental/status-code-other-error.json +++ b/adapters/trustx/trustxtest/supplemental/bad-status-500.json @@ -1,113 +1,94 @@ { "mockBidRequest": { "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, "imp": [ { "id": "test-imp-id", "video": { - "w": 1920, - "h": 1080, "mimes": [ - "video/x-flv", "video/mp4" - ] + ], + "w": 1920, + "h": 1080 }, "ext": { "bidder": { - "publisherId": "pub123", - "placementId": "placement123" + "uid": 1234 } } } ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" + "app": { + "bundle": "app-bundle" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" } }, "httpCalls": [ { "expectedRequest": { - "method": "GET", + "method": "POST", + "uri": "https://test.localhost.com", "headers": { - "Referer": [ - "http://site.com/ref" - ], - "Origin": [ - "site.com" - ], "Accept": [ "application/json" ], "Content-Type": [ "application/json;charset=utf-8" ], + "X-Openrtb-Version": [ + "2.6" + ], "User-Agent": [ - "user-agent" + "ua" ], "X-Forwarded-For": [ - "1.2.3.4" - ], - "X-Openrtb-Version": [ - "2.5" + "123.123.123.123" ] }, - "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", "body": { "id": "test-request-id", - "user": { - "buyeruid": "userId", - "yob": 1990 - }, - "device": { - "ua": "user-agent", - "ip": "1.2.3.4" - }, "imp": [ { "id": "test-imp-id", "video": { - "w": 1920, - "h": 1080, "mimes": [ - "video/x-flv", "video/mp4" - ] + ], + "w": 1920, + "h": 1080 }, "ext": { "bidder": { - "publisherId": "pub123", - "placementId": "placement123" + "uid": 1234 } } } ], - "site": { - "domain": "site.com", - "page": "http://site.com/page", - "ref": "http://site.com/ref" + "app": { + "bundle": "app-bundle" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" } }, - "impIDs":["test-imp-id"] + "impIDs": [ + "test-imp-id" + ] }, "mockResponse": { - "status": 505 + "status": 500 } } ], "expectedMakeBidsErrors": [ { - "value": "Unexpected status code: 505. Run with request.debug = 1 for more info", + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", "comparison": "literal" } ] } + diff --git a/adapters/trustx/trustxtest/supplemental/invalid-bid-ext.json b/adapters/trustx/trustxtest/supplemental/invalid-bid-ext.json new file mode 100644 index 0000000000..17f20ad731 --- /dev/null +++ b/adapters/trustx/trustxtest/supplemental/invalid-bid-ext.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "app": { + "bundle": "app-bundle" + }, + "device": { + "ua": "ua", + "ip": "123.123.123.123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ], + "User-Agent": [ + "ua" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "https://test.localhost.com", + "body": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "device": { + "ua": "ua", + "ip": "123.123.123.123" + }, + "app": { + "bundle": "app-bundle" + } + }, + "impIDs": [ + "test-imp" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "price": 10, + "impid": "test-imp", + "adm": "", + "mtype": 1, + "ext": { + "bidder": { + "trustx": { + "networkName": 1 + } + } + } + } + ] + } + ], + "seat": "trustx" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "price": 10, + "impid": "test-imp", + "adm": "", + "mtype": 1, + "ext": { + "bidder": { + "trustx": { + "networkName": 1 + } + } + } + }, + "type": "banner", + "meta": {} + } + ], + "seat": "trustx" + } + ] +} diff --git a/adapters/trustx/trustxtest/supplemental/invalid-imp-ext.json b/adapters/trustx/trustxtest/supplemental/invalid-imp-ext.json new file mode 100644 index 0000000000..8260bae301 --- /dev/null +++ b/adapters/trustx/trustxtest/supplemental/invalid-imp-ext.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "tagid": "123", + "banner": { + "w": 300, + "h": 250 + }, + "ext": 1 + } + ], + "site": { + "domain": "test-domain.com", + "page": "http://test-domain.com/index", + "ref": "https://example.com/page" + }, + "device": { + "ua": "ua", + "ipv6": "2001:0db8:85a3:0000:0000:8a2e:0370:7334" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Origin": [ + "test-domain.com" + ], + "X-Openrtb-Version": [ + "2.6" + ], + "User-Agent": [ + "ua" + ], + "X-Forwarded-For": [ + "2001:0db8:85a3:0000:0000:8a2e:0370:7334" + ], + "Referer": [ + "https://example.com/page" + ] + }, + "uri": "https://test.localhost.com", + "body": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "tagid": "123", + "banner": { + "w": 300, + "h": 250 + }, + "ext": 1 + } + ], + "site": { + "domain": "test-domain.com", + "page": "http://test-domain.com/index", + "ref": "https://example.com/page" + }, + "device": { + "ua": "ua", + "ipv6": "2001:0db8:85a3:0000:0000:8a2e:0370:7334" + } + }, + "impIDs": [ + "test-imp" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "price": 10, + "impid": "test-imp", + "adm": "", + "mtype": 1 + } + ] + } + ], + "seat": "trustx" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "crid": "4235d4b1-e2a6-9bbb-a34c-766714c2d221", + "price": 10, + "impid": "test-imp", + "adm": "", + "mtype": 1 + }, + "type": "banner" + } + ], + "seat": "trustx" + } + ] +} diff --git a/adapters/trustx/trustxtest/supplemental/no-content-response.json b/adapters/trustx/trustxtest/supplemental/no-content-response.json new file mode 100644 index 0000000000..5d65dc0e73 --- /dev/null +++ b/adapters/trustx/trustxtest/supplemental/no-content-response.json @@ -0,0 +1,89 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "app": { + "bundle": "app-bundle" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "uri": "https://test.localhost.com", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ], + "User-Agent": [ + "ua" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "body": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "app": { + "bundle": "app-bundle" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" + } + }, + "impIDs": [ + "test-imp" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} + diff --git a/adapters/trustx/trustxtest/supplemental/unsupported-mtype.json b/adapters/trustx/trustxtest/supplemental/unsupported-mtype.json new file mode 100644 index 0000000000..0596f43cf5 --- /dev/null +++ b/adapters/trustx/trustxtest/supplemental/unsupported-mtype.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "app": { + "bundle": "app-bundle" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "uri": "https://test.localhost.com", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.6" + ], + "User-Agent": [ + "ua" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "body": { + "id": "test-request", + "imp": [ + { + "id": "test-imp", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "uid": 1234 + } + } + } + ], + "app": { + "bundle": "app-bundle" + }, + "device": { + "ip": "123.123.123.123", + "ua": "ua" + } + }, + "impIDs": [ + "test-imp" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request", + "seatbid": [ + { + "bid": [ + { + "id": "2315f4a3-f2c4-8cac-69de-985272e1d706", + "impid": "test-imp", + "price": 10, + "adm": "test-ad", + "crid": "creative", + "w": 1920, + "h": 1080, + "mtype": 0, + "dur": 15 + } + ], + "seat": "trustx" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unsupported MType: 0", + "comparison": "literal" + } + ] +} + diff --git a/adapters/ucfunnel/params_test.go b/adapters/ucfunnel/params_test.go index 47954e8aad..ca9556ff6b 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 efee7736d4..e48c3dd158 100644 --- a/adapters/ucfunnel/ucfunnel.go +++ b/adapters/ucfunnel/ucfunnel.go @@ -7,11 +7,11 @@ import ( "net/url" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type UcfunnelAdapter struct { diff --git a/adapters/ucfunnel/ucfunnel_test.go b/adapters/ucfunnel/ucfunnel_test.go index ec1b777c79..0e0500a0ea 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/v3/adapters" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/undertone/params_test.go b/adapters/undertone/params_test.go index dad74a08e8..126a8c4afa 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/undertone/undertone.go b/adapters/undertone/undertone.go index 91b2527c6d..522a4a8857 100644 --- a/adapters/undertone/undertone.go +++ b/adapters/undertone/undertone.go @@ -8,11 +8,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const adapterId = 4 diff --git a/adapters/undertone/undertone_test.go b/adapters/undertone/undertone_test.go index 45281a1d15..5c55412184 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/unicorn/params_test.go b/adapters/unicorn/params_test.go index 89768ea824..8080688400 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/unicorn/unicorn.go b/adapters/unicorn/unicorn.go index a957cff9a1..ebaaab17fc 100644 --- a/adapters/unicorn/unicorn.go +++ b/adapters/unicorn/unicorn.go @@ -8,11 +8,11 @@ import ( "github.com/buger/jsonparser" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/unicorn/unicorn_test.go b/adapters/unicorn/unicorn_test.go index a83951277f..646001927f 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/unruly/params_test.go b/adapters/unruly/params_test.go index 132afee8e1..cbda246310 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/unruly/unruly.go b/adapters/unruly/unruly.go index c8e73de99b..4acf708f25 100644 --- a/adapters/unruly/unruly.go +++ b/adapters/unruly/unruly.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/unruly/unruly_test.go b/adapters/unruly/unruly_test.go index e3df3d8881..dc86bb3e68 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/vidazoo/params_test.go b/adapters/vidazoo/params_test.go index cfd3e9b5d4..42d77bdd6c 100644 --- a/adapters/vidazoo/params_test.go +++ b/adapters/vidazoo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/vidazoo/vidazoo.go b/adapters/vidazoo/vidazoo.go index 8150f4ff4b..645a867733 100644 --- a/adapters/vidazoo/vidazoo.go +++ b/adapters/vidazoo/vidazoo.go @@ -8,11 +8,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/vidazoo/vidazoo_test.go b/adapters/vidazoo/vidazoo_test.go index 5d6090de95..49116c425f 100644 --- a/adapters/vidazoo/vidazoo_test.go +++ b/adapters/vidazoo/vidazoo_test.go @@ -3,9 +3,9 @@ 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" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/videobyte/params_test.go b/adapters/videobyte/params_test.go index ffb37f88d9..977409c11c 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 ed79c6525b..5968d9257b 100644 --- a/adapters/videobyte/videobyte.go +++ b/adapters/videobyte/videobyte.go @@ -6,11 +6,11 @@ import ( "net/http" "net/url" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) diff --git a/adapters/videobyte/videobyte_test.go b/adapters/videobyte/videobyte_test.go index 2d1d2a07fd..cd5cdf5124 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/v3/config" + "github.com/prebid/prebid-server/v4/config" - "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/videoheroes/params_test.go b/adapters/videoheroes/params_test.go index e8af1f1fcf..f927d5724c 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/videoheroes/videoheroes.go b/adapters/videoheroes/videoheroes.go index 8d1d7450cb..80956d56dc 100755 --- a/adapters/videoheroes/videoheroes.go +++ b/adapters/videoheroes/videoheroes.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/videoheroes/videoheroes_test.go b/adapters/videoheroes/videoheroes_test.go index 3545b601dc..c999441007 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/vidoomy/params_test.go b/adapters/vidoomy/params_test.go index b3801c637c..1052816be5 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 b39448a414..c7dda9c774 100644 --- a/adapters/vidoomy/vidoomy.go +++ b/adapters/vidoomy/vidoomy.go @@ -7,12 +7,12 @@ import ( "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" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) type adapter struct { diff --git a/adapters/vidoomy/vidoomy_test.go b/adapters/vidoomy/vidoomy_test.go index ef561b596b..c6950cf8b4 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestVidoomyBidderEndpointConfig(t *testing.T) { diff --git a/adapters/visiblemeasures/params_test.go b/adapters/visiblemeasures/params_test.go index b4e5bb66c1..e4bbbe2885 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/visiblemeasures/visiblemeasures.go b/adapters/visiblemeasures/visiblemeasures.go index 100ba03e59..a024c5e3a4 100644 --- a/adapters/visiblemeasures/visiblemeasures.go +++ b/adapters/visiblemeasures/visiblemeasures.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/visiblemeasures/visiblemeasures_test.go b/adapters/visiblemeasures/visiblemeasures_test.go index 8203893835..718c4b2dea 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/visx/params_test.go b/adapters/visx/params_test.go index 1355d6f8d9..de8925866e 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/visx/visx.go b/adapters/visx/visx.go index 36f62ab298..2014ef3a63 100644 --- a/adapters/visx/visx.go +++ b/adapters/visx/visx.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type VisxAdapter struct { diff --git a/adapters/visx/visx_test.go b/adapters/visx/visx_test.go index d2adffddce..dd1dd999f7 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/vox/params_test.go b/adapters/vox/params_test.go index 536503555e..5438bc9dff 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/vox/vox.go b/adapters/vox/vox.go index 3e5f03aa6e..5918e2dba9 100644 --- a/adapters/vox/vox.go +++ b/adapters/vox/vox.go @@ -5,10 +5,10 @@ import ( "fmt" "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/vox/vox_test.go b/adapters/vox/vox_test.go index dce89de3af..4e057e2b27 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/vrtcal/params_test.go b/adapters/vrtcal/params_test.go index 8ba180db2b..1e0aa94874 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 e0df0bca95..d342fc44c1 100644 --- a/adapters/vrtcal/vrtcal.go +++ b/adapters/vrtcal/vrtcal.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type VrtcalAdapter struct { diff --git a/adapters/vrtcal/vrtcal_test.go b/adapters/vrtcal/vrtcal_test.go index 59d29aaee3..72efdd5f18 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/vungle/param_test.go b/adapters/vungle/param_test.go index 7053669edf..114637d27d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/vungle/vungle.go b/adapters/vungle/vungle.go index eac9eb6b3c..cbd8102d81 100644 --- a/adapters/vungle/vungle.go +++ b/adapters/vungle/vungle.go @@ -9,10 +9,10 @@ import ( "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/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const SupportedCurrency = "USD" diff --git a/adapters/vungle/vungle_test.go b/adapters/vungle/vungle_test.go index 740208dbe0..687edb21bc 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/xeworks/params_test.go b/adapters/xeworks/params_test.go index 0ce8d99f48..0581e0570f 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/xeworks/xeworks.go b/adapters/xeworks/xeworks.go index bd9d179528..10598b6750 100644 --- a/adapters/xeworks/xeworks.go +++ b/adapters/xeworks/xeworks.go @@ -7,12 +7,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type bidType struct { diff --git a/adapters/xeworks/xeworks_test.go b/adapters/xeworks/xeworks_test.go index 842045af1d..f8c566fe42 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/yahooAds/params_test.go b/adapters/yahooAds/params_test.go index 42a5c16ae7..9da14a18b0 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // This file actually intends to test static/bidder-params/yahooAds.json diff --git a/adapters/yahooAds/promote_regs_test.go b/adapters/yahooAds/promote_regs_test.go new file mode 100644 index 0000000000..6ed9a428a7 --- /dev/null +++ b/adapters/yahooAds/promote_regs_test.go @@ -0,0 +1,256 @@ +package yahooAds + +import ( + "encoding/json" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" +) + +func regsExt(j string) *openrtb2.Regs { + return &openrtb2.Regs{Ext: []byte(j)} +} + +// TestPromoteRegsExtTo26 exercises the regs.ext promotion in isolation; the +// JSON fixtures cover the same logic end-to-end through MakeRequests. +func TestPromoteRegsExtTo26(t *testing.T) { + tests := []struct { + name string + inRegs *openrtb2.Regs + wantGPP string + wantGPPSID []int8 + wantExt string // expected regs.ext JSON when it should remain + wantNoExt bool // expect regs.ext to be empty/nil after the call + wantRegsUnchanged bool + wantWarning bool // expect one errortypes.Warning + }{ + { + name: "nil_regs", + inRegs: nil, + wantRegsUnchanged: true, + }, + { + name: "regs_without_ext", + inRegs: &openrtb2.Regs{}, + wantNoExt: true, + wantRegsUnchanged: true, + }, + { + name: "regs_with_empty_ext_bytes", + inRegs: &openrtb2.Regs{Ext: []byte{}}, + wantNoExt: true, + wantRegsUnchanged: true, + }, + { + name: "regs_with_empty_object_ext", + inRegs: regsExt(`{}`), + wantExt: `{}`, + wantRegsUnchanged: true, + }, + { + name: "regs_ext_array_not_object", + inRegs: regsExt(`[1,2,3]`), + wantExt: `[1,2,3]`, + wantRegsUnchanged: true, + wantWarning: true, + }, + { + name: "regs_ext_number_not_object", + inRegs: regsExt(`42`), + wantExt: `42`, + wantRegsUnchanged: true, + wantWarning: true, + }, + { + name: "promote_gpp_only", + inRegs: regsExt(`{"gpp":"DBA"}`), + wantGPP: "DBA", + wantNoExt: true, + }, + { + name: "promote_gpp_sid_only", + inRegs: regsExt(`{"gpp_sid":[6,7]}`), + wantGPPSID: []int8{6, 7}, + wantNoExt: true, + }, + { + name: "promote_both_gpp_fields_together", + inRegs: regsExt(`{"gpp":"X","gpp_sid":[6]}`), + wantGPP: "X", + wantGPPSID: []int8{6}, + wantNoExt: true, + }, + { + name: "promote_with_unrelated_sibling_gpc", + inRegs: regsExt(`{"gpp":"X","gpp_sid":[6],"gpc":"1"}`), + wantGPP: "X", + wantGPPSID: []int8{6}, + wantExt: `{"gpc":"1"}`, + }, + { + name: "promote_gpp_keep_dsa_object_in_ext", + inRegs: regsExt(`{"gpp":"X","dsa":{"dsarequired":1}}`), + wantGPP: "X", + wantExt: `{"dsa":{"dsarequired":1}}`, + }, + { + name: "wrong_type_gpp_number_stays_in_ext", + inRegs: regsExt(`{"gpp":123,"gpp_sid":[6]}`), + wantGPPSID: []int8{6}, + wantExt: `{"gpp":123}`, + }, + { + name: "wrong_type_gpp_sid_string_stays_in_ext", + inRegs: regsExt(`{"gpp":"X","gpp_sid":"oops"}`), + wantGPP: "X", + wantExt: `{"gpp_sid":"oops"}`, + }, + { + name: "wrong_type_only_regs_untouched", + inRegs: regsExt(`{"gpp":123}`), + wantExt: `{"gpp":123}`, + wantRegsUnchanged: true, + }, + { + name: "promote_gpp_empty_string_consumed", + inRegs: regsExt(`{"gpp":""}`), + wantGPP: "", + wantNoExt: true, + }, + { + name: "promote_gpp_sid_empty_array", + inRegs: regsExt(`{"gpp_sid":[]}`), + wantGPPSID: []int8{}, + wantNoExt: true, + }, + { + name: "top_gpp_already_set_ext_duplicate_stripped", + inRegs: &openrtb2.Regs{ + GPP: "EXISTING", + Ext: []byte(`{"gpp":"EXT_VALUE"}`), + }, + wantGPP: "EXISTING", + wantNoExt: true, + }, + { + name: "top_gpp_sid_already_set_ext_duplicate_stripped", + inRegs: &openrtb2.Regs{ + GPPSID: []int8{1, 2}, + Ext: []byte(`{"gpp_sid":[6]}`), + }, + wantGPPSID: []int8{1, 2}, + wantNoExt: true, + }, + { + name: "top_gpp_set_duplicate_stripped_sibling_kept", + inRegs: &openrtb2.Regs{ + GPP: "KEEP", + Ext: []byte(`{"gpp":"stale","gpc":"1"}`), + }, + wantGPP: "KEEP", + wantExt: `{"gpc":"1"}`, + }, + { + name: "top_gpp_set_wrong_typed_duplicate_also_stripped", + inRegs: &openrtb2.Regs{ + GPP: "KEEP", + Ext: []byte(`{"gpp":123}`), + }, + wantGPP: "KEEP", + wantNoExt: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, warnings := promoteRegsExtTo26(tt.inRegs) + + if tt.wantWarning { + require.Len(t, warnings, 1) + assert.IsType(t, &errortypes.Warning{}, warnings[0]) + } else { + assert.Empty(t, warnings) + } + + if tt.wantRegsUnchanged { + assert.Same(t, tt.inRegs, got, "regs pointer should NOT change for no-op input") + } else { + assert.NotSame(t, tt.inRegs, got, "regs should be swapped to a fresh copy after promotion") + } + + if got == nil { + return + } + + assert.Equal(t, tt.wantGPP, got.GPP, "regs.gpp") + assert.Equal(t, tt.wantGPPSID, got.GPPSID, "regs.gpp_sid") + + switch { + case tt.wantNoExt: + assert.Empty(t, got.Ext, "regs.ext should be empty/nil") + case tt.wantExt != "": + var gotExt, wantExt any + require.NoError(t, json.Unmarshal(got.Ext, &gotExt), "regs.ext should be valid JSON") + require.NoError(t, json.Unmarshal([]byte(tt.wantExt), &wantExt)) + assert.Equal(t, wantExt, gotExt, "regs.ext content") + default: + t.Fatal("test case must set wantNoExt or wantExt") + } + }) + } +} + +// The original *Regs must never be mutated: other adapters and per-impression +// copies must keep seeing the publisher's original request shape. +func TestPromoteRegsExtTo26_DoesNotMutateOriginalRegs(t *testing.T) { + originalExt := []byte(`{"gpp":"X","gpp_sid":[6],"gpc":"1"}`) + originalRegs := &openrtb2.Regs{Ext: append([]byte(nil), originalExt...)} + + beforeGPP := originalRegs.GPP + beforeGPPSID := append([]int8(nil), originalRegs.GPPSID...) + beforeExt := append([]byte(nil), originalRegs.Ext...) + + got, warnings := promoteRegsExtTo26(originalRegs) + + assert.Empty(t, warnings) + assert.Equal(t, beforeGPP, originalRegs.GPP, "original Regs.GPP was mutated") + assert.Equal(t, beforeGPPSID, originalRegs.GPPSID, "original Regs.GPPSID was mutated") + assert.Equal(t, beforeExt, []byte(originalRegs.Ext), "original Regs.Ext bytes were mutated") + + assert.NotSame(t, originalRegs, got, "promoted regs should be a fresh copy") + assert.Equal(t, "X", got.GPP) + assert.Equal(t, []int8{6}, got.GPPSID) + assert.JSONEq(t, `{"gpc":"1"}`, string(got.Ext), "gpc stays in ext") +} + +// A regs.ext warning must not drop the impression: the bid request still goes +// out, with regs.ext passed through untouched. +func TestMakeRequestsMalformedRegsExtWarning(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderYahooAds, config.Adapter{}, config.Server{}) + require.NoError(t, buildErr) + + 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: []byte(`{"bidder":{"dcn":"dcn1","pos":"pos2"}}`), + }}, + Site: &openrtb2.Site{ID: "test-site-id"}, + Regs: &openrtb2.Regs{Ext: []byte(`[1,2,3]`)}, + } + + reqs, errs := bidder.MakeRequests(request, &adapters.ExtraRequestInfo{}) + + require.Len(t, errs, 1) + assert.IsType(t, &errortypes.Warning{}, errs[0]) + require.Len(t, reqs, 1, "impression must not be dropped on a regs.ext warning") + assert.Contains(t, string(reqs[0].Body), `"ext":[1,2,3]`, "regs.ext should pass through untouched") +} diff --git a/adapters/yahooAds/yahooAds.go b/adapters/yahooAds/yahooAds.go index 4a03bc3e7f..18c94aa985 100644 --- a/adapters/yahooAds/yahooAds.go +++ b/adapters/yahooAds/yahooAds.go @@ -6,12 +6,12 @@ import ( "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" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) type adapter struct { @@ -26,12 +26,17 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E headers.Add("Content-Type", "application/json;charset=utf-8") headers.Add("Accept", "application/json") - headers.Add("x-openrtb-version", "2.5") + headers.Add("x-openrtb-version", "2.6") if request.Device != nil && request.Device.UA != "" { headers.Set("User-Agent", request.Device.UA) } + // Regs depends only on request-level data, so promote once and reuse the + // result for every per-impression copy. + promotedRegs, regsWarnings := promoteRegsExtTo26(request.Regs) + errors = append(errors, regsWarnings...) + for idx, imp := range request.Imp { var bidderExt adapters.ExtImpBidder err := jsonutil.Unmarshal(imp.Ext, &bidderExt) @@ -57,6 +62,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E // each split request is only associated to a single impression reqCopy := *request reqCopy.Imp = []openrtb2.Imp{imp} + reqCopy.Regs = promotedRegs if request.Site != nil { siteCopy := *request.Site @@ -172,37 +178,73 @@ func changeRequestForBidService(request *openrtb2.BidRequest, extension *openrtb } } - if request.Regs != nil && request.Regs.GPP != "" { - requestRegs := *request.Regs - if requestRegs.Ext == nil { - requestRegs.Ext = json.RawMessage("{}") - } - var regsExt map[string]json.RawMessage - err := jsonutil.Unmarshal(requestRegs.Ext, ®sExt) - if err != nil { - return err - } - regsExt["gpp"], err = json.Marshal(&requestRegs.GPP) - if err != nil { - return fmt.Errorf("failed to marshal requestRegs.GPP: %v", err) + return nil +} + +// promoteRegsExtTo26 moves regs.ext.{gpp, gpp_sid} to their top-level fields +// when the publisher sent them in ext and the top-level field is empty. +// When the top-level field is already set, the ext duplicate is removed so +// only the authoritative top-level value ships. A regs.ext that is not a JSON +// object is passed through untouched with a non-fatal warning. +func promoteRegsExtTo26(regs *openrtb2.Regs) (*openrtb2.Regs, []error) { + if regs == nil || len(regs.Ext) == 0 { + return regs, nil + } + + var regsExt map[string]json.RawMessage + if err := jsonutil.Unmarshal(regs.Ext, ®sExt); err != nil { + return regs, []error{&errortypes.Warning{ + Message: "regs.ext is not a JSON object; skipped OpenRTB 2.6 regs promotion", + }} + } + + regsCopy := *regs + modified := false + + if raw, ok := regsExt["gpp"]; ok { + if regsCopy.GPP == "" { + var v string + if err := jsonutil.Unmarshal(raw, &v); err == nil { + regsCopy.GPP = v + delete(regsExt, "gpp") + modified = true + } + } else { + delete(regsExt, "gpp") + modified = true } - if requestRegs.GPPSID != nil { - regsExt["gpp_sid"], err = json.Marshal(&requestRegs.GPPSID) - if err != nil { - return err + } + + if raw, ok := regsExt["gpp_sid"]; ok { + if len(regsCopy.GPPSID) == 0 { + var v []int8 + if err := jsonutil.Unmarshal(raw, &v); err == nil { + regsCopy.GPPSID = v + delete(regsExt, "gpp_sid") + modified = true } + } else { + delete(regsExt, "gpp_sid") + modified = true } + } + + if !modified { + return regs, nil + } - requestRegs.Ext, err = json.Marshal(®sExt) + if len(regsExt) == 0 { + regsCopy.Ext = nil + } else { + // stdlib json.Marshal is used because it writes a nil RawMessage as null. + newExt, err := json.Marshal(regsExt) if err != nil { - return err + return regs, nil } - requestRegs.GPP = "" - requestRegs.GPPSID = nil - request.Regs = &requestRegs + regsCopy.Ext = newExt } - return nil + return ®sCopy, nil } func validateBanner(banner *openrtb2.Banner) error { diff --git a/adapters/yahooAds/yahooAds_test.go b/adapters/yahooAds/yahooAds_test.go index 0eaf711faf..6b07ef32c1 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestYahooAdsBidderEndpointConfig(t *testing.T) { diff --git a/adapters/yahooAds/yahooAdstest/exemplary/simple-app-banner.json b/adapters/yahooAds/yahooAdstest/exemplary/simple-app-banner.json index 6b61861d9b..2b2a451cb1 100644 --- a/adapters/yahooAds/yahooAdstest/exemplary/simple-app-banner.json +++ b/adapters/yahooAds/yahooAdstest/exemplary/simple-app-banner.json @@ -39,7 +39,7 @@ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" ], "X-Openrtb-Version": [ - "2.5" + "2.6" ] }, "uri": "", diff --git a/adapters/yahooAds/yahooAdstest/exemplary/simple-banner.json b/adapters/yahooAds/yahooAdstest/exemplary/simple-banner.json index 3d0b4a37b0..8253ac8853 100644 --- a/adapters/yahooAds/yahooAdstest/exemplary/simple-banner.json +++ b/adapters/yahooAds/yahooAdstest/exemplary/simple-banner.json @@ -39,7 +39,7 @@ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" ], "X-Openrtb-Version": [ - "2.5" + "2.6" ] }, "uri": "", diff --git a/adapters/yahooAds/yahooAdstest/exemplary/simple-video.json b/adapters/yahooAds/yahooAdstest/exemplary/simple-video.json index 9f9d188d00..e30a70df25 100644 --- a/adapters/yahooAds/yahooAdstest/exemplary/simple-video.json +++ b/adapters/yahooAds/yahooAdstest/exemplary/simple-video.json @@ -47,7 +47,7 @@ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" ], "X-Openrtb-Version": [ - "2.5" + "2.6" ] }, "uri": "", diff --git a/adapters/yahooAds/yahooAdstest/supplemental/non-supported-requests-bids-ignored.json b/adapters/yahooAds/yahooAdstest/supplemental/non-supported-requests-bids-ignored.json index 5e0820761d..b5e83649f0 100644 --- a/adapters/yahooAds/yahooAdstest/supplemental/non-supported-requests-bids-ignored.json +++ b/adapters/yahooAds/yahooAdstest/supplemental/non-supported-requests-bids-ignored.json @@ -38,7 +38,7 @@ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" ], "X-Openrtb-Version": [ - "2.5" + "2.6" ] }, "uri": "", diff --git a/adapters/yahooAds/yahooAdstest/supplemental/server-response-wrong-impid.json b/adapters/yahooAds/yahooAdstest/supplemental/server-response-wrong-impid.json index a831dba64b..c5f3f47c01 100644 --- a/adapters/yahooAds/yahooAdstest/supplemental/server-response-wrong-impid.json +++ b/adapters/yahooAds/yahooAdstest/supplemental/server-response-wrong-impid.json @@ -38,7 +38,7 @@ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" ], "X-Openrtb-Version": [ - "2.5" + "2.6" ] }, "uri": "", diff --git a/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-overwrite.json b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-ext-duplicate-stripped.json similarity index 97% rename from adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-overwrite.json rename to adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-ext-duplicate-stripped.json index 950796692a..bcd41b7e56 100644 --- a/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-overwrite.json +++ b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-ext-duplicate-stripped.json @@ -47,7 +47,7 @@ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" ], "X-Openrtb-Version": [ - "2.5" + "2.6" ] }, "uri": "", @@ -78,9 +78,9 @@ "id": "dcn1" }, "regs": { + "gpp": "header~1YNN", + "gpp_sid": [6], "ext": { - "gpp": "header~1YNN", - "gpp_sid": [6], "param1": "val1" } } diff --git a/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-ext-promoted.json b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-ext-promoted.json new file mode 100644 index 0000000000..cd29e6cde9 --- /dev/null +++ b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-ext-promoted.json @@ -0,0 +1,148 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "123", + "ext": { + "bidder": { + "dcn": "dcn1", + "pos": "pos2" + } + } + } + ], + "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" + }, + "site": { + "id": "test-site-id" + }, + "regs": { + "ext": { + "gpp": "header~1YNN", + "gpp_sid": [ + 6 + ], + "gpc": "1" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "", + "body": { + "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" + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "pos2", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ], + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "dcn": "dcn1", + "pos": "pos2" + } + } + } + ], + "site": { + "id": "dcn1" + }, + "regs": { + "gpp": "header~1YNN", + "gpp_sid": [ + 6 + ], + "ext": { + "gpc": "1" + } + } + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "yahooAds", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728 + } + ] + } + ], + "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": "crid_10", + "w": 728, + "h": 90 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp.json b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp.json index 73012144fb..d8b9c22a32 100644 --- a/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp.json +++ b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp.json @@ -43,7 +43,7 @@ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" ], "X-Openrtb-Version": [ - "2.5" + "2.6" ] }, "uri": "", @@ -74,10 +74,8 @@ "id": "dcn1" }, "regs": { - "ext": { - "gpp": "header~1YNN", - "gpp_sid": [6] - } + "gpp": "header~1YNN", + "gpp_sid": [6] } }, "impIDs":["test-imp-id"] diff --git a/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-ignore-width-when-height-missing.json b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-ignore-width-when-height-missing.json index 513e37f9f1..92b575369f 100644 --- a/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-ignore-width-when-height-missing.json +++ b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-ignore-width-when-height-missing.json @@ -40,7 +40,7 @@ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" ], "X-Openrtb-Version": [ - "2.5" + "2.6" ] }, "uri": "", diff --git a/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-two-imps-shared-regs.json b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-two-imps-shared-regs.json new file mode 100644 index 0000000000..eddd62ee93 --- /dev/null +++ b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-two-imps-shared-regs.json @@ -0,0 +1,235 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-1", + "banner": { + "format": [{"w": 300, "h": 250}] + }, + "ext": { + "bidder": { + "dcn": "dcn1", + "pos": "pos2" + } + } + }, + { + "id": "test-imp-2", + "banner": { + "format": [{"w": 728, "h": 90}] + }, + "ext": { + "bidder": { + "dcn": "dcn1", + "pos": "pos3" + } + } + } + ], + "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" + }, + "site": { + "id": "test-site-id" + }, + "regs": { + "ext": { + "gpp": "header~1YNN", + "gpp_sid": [6], + "gpc": "1" + } + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "", + "body": { + "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" + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-1", + "tagid": "pos2", + "banner": { + "format": [{"w": 300, "h": 250}], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "dcn": "dcn1", + "pos": "pos2" + } + } + } + ], + "site": { + "id": "dcn1" + }, + "regs": { + "gpp": "header~1YNN", + "gpp_sid": [6], + "ext": { + "gpc": "1" + } + } + }, + "impIDs": ["test-imp-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "yahooAds", + "bid": [{ + "id": "bid-1", + "impid": "test-imp-1", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 250, + "w": 300 + }] + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" + ], + "X-Openrtb-Version": [ + "2.6" + ] + }, + "uri": "", + "body": { + "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" + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-2", + "tagid": "pos3", + "banner": { + "format": [{"w": 728, "h": 90}], + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "dcn": "dcn1", + "pos": "pos3" + } + } + } + ], + "site": { + "id": "dcn1" + }, + "regs": { + "gpp": "header~1YNN", + "gpp_sid": [6], + "ext": { + "gpc": "1" + } + } + }, + "impIDs": ["test-imp-2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "yahooAds", + "bid": [{ + "id": "bid-2", + "impid": "test-imp-2", + "price": 0.750000, + "adm": "some-test-ad-2", + "crid": "crid_11", + "h": 90, + "w": 728 + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "test-imp-1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 300, + "h": 250 + }, + "type": "banner" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-2", + "impid": "test-imp-2", + "price": 0.75, + "adm": "some-test-ad-2", + "crid": "crid_11", + "w": 728, + "h": 90 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/yandex/params_test.go b/adapters/yandex/params_test.go index 0805be1988..d3b872728c 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/yandex/yandex.go b/adapters/yandex/yandex.go index c6a99e5a2e..e26aba5e94 100644 --- a/adapters/yandex/yandex.go +++ b/adapters/yandex/yandex.go @@ -11,12 +11,12 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/adapters/yandex/yandex_test.go b/adapters/yandex/yandex_test.go index 7635b1a1b9..29a7feff16 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/yeahmobi/params_test.go b/adapters/yeahmobi/params_test.go index 2b47316df2..8366c19260 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/yeahmobi/yeahmobi.go b/adapters/yeahmobi/yeahmobi.go index 934cee5c27..f3b314ad92 100644 --- a/adapters/yeahmobi/yeahmobi.go +++ b/adapters/yeahmobi/yeahmobi.go @@ -8,12 +8,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/yeahmobi/yeahmobi_test.go b/adapters/yeahmobi/yeahmobi_test.go index d822b32d67..452ec6e781 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/yieldlab/params_test.go b/adapters/yieldlab/params_test.go index ac65adc0fe..6ac8fa727b 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 57ee15c923..4740b042ec 100644 --- a/adapters/yieldlab/types.go +++ b/adapters/yieldlab/types.go @@ -4,7 +4,7 @@ import ( "strconv" "time" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type bidResponse struct { diff --git a/adapters/yieldlab/yieldlab.go b/adapters/yieldlab/yieldlab.go index 4466e548af..4193547117 100644 --- a/adapters/yieldlab/yieldlab.go +++ b/adapters/yieldlab/yieldlab.go @@ -12,12 +12,12 @@ import ( "golang.org/x/text/currency" "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" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) // YieldlabAdapter connects the Yieldlab API to prebid server diff --git a/adapters/yieldlab/yieldlab_test.go b/adapters/yieldlab/yieldlab_test.go index 1bea9b12ea..b9fe8ed8a5 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const testURL = "https://ad.yieldlab.net/testing/" diff --git a/adapters/yieldmo/params_test.go b/adapters/yieldmo/params_test.go index baa566cf71..7c9224180c 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 0725f7920c..c4ea2c66d9 100644 --- a/adapters/yieldmo/yieldmo.go +++ b/adapters/yieldmo/yieldmo.go @@ -7,11 +7,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type YieldmoAdapter struct { diff --git a/adapters/yieldmo/yieldmo_test.go b/adapters/yieldmo/yieldmo_test.go index 668e0a375e..62ec8d5dd8 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/yieldone/params_test.go b/adapters/yieldone/params_test.go index 5632546ac3..9f493a6d18 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/yieldone/yieldone.go b/adapters/yieldone/yieldone.go index b1aa646538..5227861c4b 100644 --- a/adapters/yieldone/yieldone.go +++ b/adapters/yieldone/yieldone.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type YieldoneAdapter struct { diff --git a/adapters/yieldone/yieldone_test.go b/adapters/yieldone/yieldone_test.go index a9831561d4..c729049201 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/zentotem/zentotem.go b/adapters/zentotem/zentotem.go index 65c067443e..428cc2c449 100644 --- a/adapters/zentotem/zentotem.go +++ b/adapters/zentotem/zentotem.go @@ -4,9 +4,9 @@ import ( "encoding/json" "fmt" "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type adapter struct { diff --git a/adapters/zentotem/zentotem_test.go b/adapters/zentotem/zentotem_test.go index cf608c4a41..2b14a34924 100644 --- a/adapters/zentotem/zentotem_test.go +++ b/adapters/zentotem/zentotem_test.go @@ -2,9 +2,9 @@ package zentotem import ( "github.com/prebid/openrtb/v20/openrtb2" - "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/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" "testing" ) diff --git a/adapters/zeroclickfraud/params_test.go b/adapters/zeroclickfraud/params_test.go new file mode 100644 index 0000000000..14682e83bb --- /dev/null +++ b/adapters/zeroclickfraud/params_test.go @@ -0,0 +1,65 @@ +package zeroclickfraud + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/openrtb_ext" +) + +var validParams = []string{ + `{ "host": "host", "sourceId": 1 }`, + `{ "host": "host.example.com", "sourceId": 1 }`, + `{ "host": "host.example.com:8080", "sourceId": 1 }`, + `{ "host": "host-example.test", "sourceId": 1 }`, + `{ "host": "Host.Example.com", "sourceId": 1 }`, + `{ "host": "localhost:3000", "sourceId": 1 }`, +} + +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.BidderZeroClickFraud, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected ZeroClickFraud params: %s", validParam) + } + } +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{ "sourceId": 1 }`, + `{ "host": "host" }`, + `{ "host": "", "sourceId": 1 }`, + `{ "host": "/path", "sourceId": 1 }`, + `{ "host": "//evil.com", "sourceId": 1 }`, + `{ "host": "host/path", "sourceId": 1 }`, + `{ "host": "host?query=1", "sourceId": 1 }`, + `{ "host": "host#fragment", "sourceId": 1 }`, + `{ "host": "user@host", "sourceId": 1 }`, + `{ "host": "https://host.com", "sourceId": 1 }`, + `{ "host": "host:notaport", "sourceId": 1 }`, + `{ "host": "host:8080:extra", "sourceId": 1 }`, +} + +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.BidderZeroClickFraud, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} diff --git a/adapters/zeroclickfraud/zeroclickfraud.go b/adapters/zeroclickfraud/zeroclickfraud.go index eecd1dd858..0bda7b3687 100644 --- a/adapters/zeroclickfraud/zeroclickfraud.go +++ b/adapters/zeroclickfraud/zeroclickfraud.go @@ -8,12 +8,13 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/urlutil" ) type ZeroClickFraudAdapter struct { @@ -149,7 +150,7 @@ func getBidderParams(imp *openrtb2.Imp) (*openrtb_ext.ExtImpZeroClickFraud, erro } } - if len(zeroclickfraudExt.Host) < 1 { + if !urlutil.IsSafeHost(zeroclickfraudExt.Host) { return nil, &errortypes.BadInput{ Message: "Invalid/Missing Host", } diff --git a/adapters/zeroclickfraud/zeroclickfraud_test.go b/adapters/zeroclickfraud/zeroclickfraud_test.go index 363f37c0e1..d10b226bc7 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/intertech/intertechtest/supplemental/invalid-ext.json b/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/invalid-host.json similarity index 53% rename from adapters/intertech/intertechtest/supplemental/invalid-ext.json rename to adapters/zeroclickfraud/zeroclickfraudtest/supplemental/invalid-host.json index 4c8eb9c9c7..edd5ca65a2 100644 --- a/adapters/intertech/intertechtest/supplemental/invalid-ext.json +++ b/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/invalid-host.json @@ -1,9 +1,9 @@ { "mockBidRequest": { - "id": "test-req-id", + "id": "test-request-id", "imp": [ { - "id": "test-imp-id", + "id": "some-impression-id", "banner": { "format": [ { @@ -12,18 +12,19 @@ } ] }, - "ext": 123 + "ext": { + "bidder": { + "host": "evil.com/path?redirect=http://attacker.com#", + "sourceId": 123 + } + } } ] }, - "httpCalls": [], - - "expectedBidResponses": [], - "expectedMakeRequestsErrors": [ { - "value": "imp #test-imp-id: unable to parse bidder ext: expect { or n, but found 1", + "value": "Invalid/Missing Host", "comparison": "literal" } ] diff --git a/adapters/zeta_global_ssp/params_test.go b/adapters/zeta_global_ssp/params_test.go index d665d3da0f..a1c26968b9 100644 --- a/adapters/zeta_global_ssp/params_test.go +++ b/adapters/zeta_global_ssp/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/zeta_global_ssp/zeta_global_ssp.go b/adapters/zeta_global_ssp/zeta_global_ssp.go index 59a912c162..9f491ed2b5 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp.go +++ b/adapters/zeta_global_ssp/zeta_global_ssp.go @@ -8,12 +8,12 @@ import ( "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/zeta_global_ssp/zeta_global_ssp_test.go b/adapters/zeta_global_ssp/zeta_global_ssp_test.go index f7e9b36698..d68b55b85a 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/zmaticoo/params_test.go b/adapters/zmaticoo/params_test.go index c6c462155a..1360bfbe96 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/zmaticoo/zmaticoo.go b/adapters/zmaticoo/zmaticoo.go index 9e0da9e449..93703d5f72 100644 --- a/adapters/zmaticoo/zmaticoo.go +++ b/adapters/zmaticoo/zmaticoo.go @@ -6,11 +6,11 @@ import ( "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type adapter struct { diff --git a/adapters/zmaticoo/zmaticoo_test.go b/adapters/zmaticoo/zmaticoo_test.go index df12c1e1b6..7bd5c6f674 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/v3/adapters/adapterstest" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters/adapterstest" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adservertargeting/adservertargeting.go b/adservertargeting/adservertargeting.go index 3ab7cefe6c..993d6387bd 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type DataSource string diff --git a/adservertargeting/adservertargeting_test.go b/adservertargeting/adservertargeting_test.go index 8ba3c256b3..10e3090d29 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/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/adservertargeting/reqcache.go b/adservertargeting/reqcache.go index 03c87f024c..c1b701bdf3 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/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type requestCache struct { diff --git a/adservertargeting/requestlookup.go b/adservertargeting/requestlookup.go index 6829971651..99545b8161 100644 --- a/adservertargeting/requestlookup.go +++ b/adservertargeting/requestlookup.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/buger/jsonparser" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 22f914ac79..c588cdf30d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adservertargeting/respdataprocessor.go b/adservertargeting/respdataprocessor.go index beeaae68de..489e5fc7b6 100644 --- a/adservertargeting/respdataprocessor.go +++ b/adservertargeting/respdataprocessor.go @@ -6,8 +6,8 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v5" ) diff --git a/adservertargeting/respdataprocessor_test.go b/adservertargeting/respdataprocessor_test.go index 973f9b801e..90215a4f1d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adservertargeting/utils.go b/adservertargeting/utils.go index 7cd4a826b9..9286c896be 100644 --- a/adservertargeting/utils.go +++ b/adservertargeting/utils.go @@ -5,8 +5,8 @@ import ( "strings" "github.com/buger/jsonparser" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func splitAndGet(path string, data []byte, delimiter string) (string, error) { diff --git a/amp/parse.go b/amp/parse.go index 2a86bc7b6b..5437ed3f91 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/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/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/privacy/ccpa" + "github.com/prebid/prebid-server/v4/privacy/gdpr" ) // Params defines the parameters of an AMP request. diff --git a/amp/parse_test.go b/amp/parse_test.go index 65b69012b4..671d9b0f05 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/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/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/privacy/ccpa" + "github.com/prebid/prebid-server/v4/privacy/gdpr" "github.com/stretchr/testify/assert" ) diff --git a/analytics/agma/agma_module.go b/analytics/agma/agma_module.go index 1e544fe606..518956d58d 100644 --- a/analytics/agma/agma_module.go +++ b/analytics/agma/agma_module.go @@ -13,10 +13,10 @@ import ( "github.com/benbjohnson/clock" "github.com/docker/go-units" "github.com/prebid/go-gdpr/vendorconsent" - "github.com/prebid/prebid-server/v3/analytics" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type httpSender = func(payload []byte) error diff --git a/analytics/agma/agma_module_test.go b/analytics/agma/agma_module_test.go index 61a6e52755..20325ebb53 100644 --- a/analytics/agma/agma_module_test.go +++ b/analytics/agma/agma_module_test.go @@ -11,9 +11,9 @@ import ( "github.com/benbjohnson/clock" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/analytics" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/analytics/agma/model.go b/analytics/agma/model.go index 112ce961a0..b48d39aebd 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/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type EventType string diff --git a/analytics/agma/model_test.go b/analytics/agma/model_test.go index 925856b87b..35340bd274 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/analytics/agma/sender.go b/analytics/agma/sender.go index e3f9c76852..28a0825b07 100644 --- a/analytics/agma/sender.go +++ b/analytics/agma/sender.go @@ -10,9 +10,9 @@ import ( "net/url" "time" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/version" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/version" ) func compressToGZIP(requestBody []byte) ([]byte, error) { diff --git a/analytics/agma/sender_test.go b/analytics/agma/sender_test.go index 1d23e6b6a9..e4a2553c9e 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/v3/config" + "github.com/prebid/prebid-server/v4/config" "github.com/stretchr/testify/assert" ) diff --git a/analytics/build/build.go b/analytics/build/build.go index faef6239a5..5851739108 100644 --- a/analytics/build/build.go +++ b/analytics/build/build.go @@ -4,16 +4,16 @@ import ( "encoding/json" "github.com/benbjohnson/clock" - "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/logger" - "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/v4/analytics" + "github.com/prebid/prebid-server/v4/analytics/agma" + "github.com/prebid/prebid-server/v4/analytics/clients" + "github.com/prebid/prebid-server/v4/analytics/filesystem" + "github.com/prebid/prebid-server/v4/analytics/pubstack" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/privacy" ) // Modules that need to be logged to need to be initialized here diff --git a/analytics/build/build_test.go b/analytics/build/build_test.go index ae16e0f749..7c6751b722 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/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/iputil" "net/http" "os" "testing" "github.com/prebid/openrtb/v20/openrtb2" - "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/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/analytics/build/msp_plugin.go b/analytics/build/msp_plugin.go index ddca06b5df..2269d33022 100644 --- a/analytics/build/msp_plugin.go +++ b/analytics/build/msp_plugin.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/golang/glog" - "github.com/prebid/prebid-server/v3/analytics" - mspPlugin "github.com/prebid/prebid-server/v3/msp/plugin" + "github.com/prebid/prebid-server/v4/analytics" + mspPlugin "github.com/prebid/prebid-server/v4/msp/plugin" ) type PluginBuilder interface { diff --git a/analytics/core.go b/analytics/core.go index 25ff46c824..a2b8162c0c 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/v3/config" - "github.com/prebid/prebid-server/v3/hooks/hookexecution" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // Module must be implemented by analytics modules to extract the required information and logging @@ -82,9 +82,8 @@ type CookieSyncBidder struct { } type UsersyncInfo struct { - URL string `json:"url,omitempty"` - Type string `json:"type,omitempty"` - SupportCORS bool `json:"supportCORS,omitempty"` + URL string `json:"url,omitempty"` + Type string `json:"type,omitempty"` } // NotificationEvent object of a transaction at /event diff --git a/analytics/filesystem/file_module.go b/analytics/filesystem/file_module.go index f2ab3c63d9..0342ee9f33 100644 --- a/analytics/filesystem/file_module.go +++ b/analytics/filesystem/file_module.go @@ -6,9 +6,9 @@ import ( cglog "github.com/chasex/glog" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/analytics" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type RequestType string diff --git a/analytics/filesystem/file_module_test.go b/analytics/filesystem/file_module_test.go index 0e502cfb9e..ff5a139ddd 100644 --- a/analytics/filesystem/file_module_test.go +++ b/analytics/filesystem/file_module_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" - "github.com/prebid/prebid-server/v3/analytics" - "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" "github.com/stretchr/testify/mock" "github.com/prebid/openrtb/v20/openrtb2" diff --git a/analytics/filesystem/model.go b/analytics/filesystem/model.go index aed111dd10..eec6fd7645 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/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" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type logAuction struct { diff --git a/analytics/pubstack/config.go b/analytics/pubstack/config.go index 38ca4cb139..6548cbc0f5 100644 --- a/analytics/pubstack/config.go +++ b/analytics/pubstack/config.go @@ -9,7 +9,7 @@ import ( "time" "github.com/docker/go-units" - "github.com/prebid/prebid-server/v3/logger" + "github.com/prebid/prebid-server/v4/logger" ) func fetchConfig(client *http.Client, endpoint *url.URL) (*Configuration, error) { diff --git a/analytics/pubstack/configupdate.go b/analytics/pubstack/configupdate.go index 166e69554d..d570d28da1 100644 --- a/analytics/pubstack/configupdate.go +++ b/analytics/pubstack/configupdate.go @@ -6,7 +6,7 @@ import ( "net/url" "time" - "github.com/prebid/prebid-server/v3/util/task" + "github.com/prebid/prebid-server/v4/util/task" ) // ConfigUpdateTask publishes configurations until the stop channel is signaled. diff --git a/analytics/pubstack/eventchannel/eventchannel.go b/analytics/pubstack/eventchannel/eventchannel.go index bde37ee546..7879a6d9d4 100644 --- a/analytics/pubstack/eventchannel/eventchannel.go +++ b/analytics/pubstack/eventchannel/eventchannel.go @@ -7,7 +7,7 @@ import ( "time" "github.com/benbjohnson/clock" - "github.com/prebid/prebid-server/v3/logger" + "github.com/prebid/prebid-server/v4/logger" ) type Metrics struct { diff --git a/analytics/pubstack/eventchannel/sender.go b/analytics/pubstack/eventchannel/sender.go index 61587ea941..3ea79e2109 100644 --- a/analytics/pubstack/eventchannel/sender.go +++ b/analytics/pubstack/eventchannel/sender.go @@ -8,7 +8,7 @@ import ( "net/url" "path" - "github.com/prebid/prebid-server/v3/logger" + "github.com/prebid/prebid-server/v4/logger" ) type Sender = func(payload []byte) error diff --git a/analytics/pubstack/helpers/json.go b/analytics/pubstack/helpers/json.go index fbdc173219..ba02a34a26 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/v3/analytics" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/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 1e6282078c..82f56e1bc3 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/v3/analytics" + "github.com/prebid/prebid-server/v4/analytics" "github.com/stretchr/testify/assert" ) diff --git a/analytics/pubstack/helpers/model.go b/analytics/pubstack/helpers/model.go index 7dad2f7dad..cdba835e43 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/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" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type logAuction struct { diff --git a/analytics/pubstack/pubstack_module.go b/analytics/pubstack/pubstack_module.go index 9a8116951d..965774043a 100644 --- a/analytics/pubstack/pubstack_module.go +++ b/analytics/pubstack/pubstack_module.go @@ -10,10 +10,10 @@ import ( "time" "github.com/benbjohnson/clock" - "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" - "github.com/prebid/prebid-server/v3/logger" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/analytics/pubstack/eventchannel" + "github.com/prebid/prebid-server/v4/analytics/pubstack/helpers" + "github.com/prebid/prebid-server/v4/logger" ) type Configuration struct { diff --git a/analytics/pubstack/pubstack_module_test.go b/analytics/pubstack/pubstack_module_test.go index e2b4e118c6..ff590010f6 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/v3/analytics" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/analytics/runner.go b/analytics/runner.go index d10370e485..42b422d55e 100644 --- a/analytics/runner.go +++ b/analytics/runner.go @@ -1,7 +1,7 @@ package analytics import ( - "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v4/privacy" ) type Runner interface { diff --git a/bidadjustment/apply.go b/bidadjustment/apply.go index 864d6bf6fb..d3063709ee 100644 --- a/bidadjustment/apply.go +++ b/bidadjustment/apply.go @@ -3,8 +3,8 @@ package bidadjustment import ( "math" - "github.com/prebid/prebid-server/v3/adapters" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const ( diff --git a/bidadjustment/apply_test.go b/bidadjustment/apply_test.go index 1a9bf75a20..529a5ab527 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/v3/adapters" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/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 2d0ac7c4cd..fbde258440 100644 --- a/bidadjustment/build_rules.go +++ b/bidadjustment/build_rules.go @@ -1,8 +1,8 @@ package bidadjustment import ( - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const ( diff --git a/bidadjustment/build_rules_test.go b/bidadjustment/build_rules_test.go index 29864bcdbc..fd7346c2ac 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/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/bidadjustment/validate.go b/bidadjustment/validate.go index b5383b4d1b..dd59f12af0 100644 --- a/bidadjustment/validate.go +++ b/bidadjustment/validate.go @@ -3,7 +3,7 @@ package bidadjustment import ( "math" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 dedcddc9af..2ac39bddd7 100644 --- a/bidadjustment/validate_test.go +++ b/bidadjustment/validate_test.go @@ -3,7 +3,7 @@ package bidadjustment import ( "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/config/account.go b/config/account.go index 2d2bfb5cd8..58b699b6da 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/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/iputil" ) // ChannelType enumerates the values of integrations Prebid Server can configure for an account @@ -41,7 +41,7 @@ type Account struct { GDPR AccountGDPR `mapstructure:"gdpr" json:"gdpr"` DebugAllow bool `mapstructure:"debug_allow" json:"debug_allow"` DefaultIntegration string `mapstructure:"default_integration" json:"default_integration"` - CookieSync CookieSync `mapstructure:"cookie_sync" json:"cookie_sync"` + CookieSync AccountCookieSync `mapstructure:"cookie_sync" json:"cookie_sync"` Events Events `mapstructure:"events" json:"events"` // Don't enable this feature. It is still under developmment - https://github.com/prebid/prebid-server/issues/1725 TruncateTargetAttribute *int `mapstructure:"truncate_target_attr" json:"truncate_target_attr"` AlternateBidderCodes *openrtb_ext.ExtAlternateBidderCodes `mapstructure:"alternatebiddercodes" json:"alternatebiddercodes"` @@ -56,12 +56,14 @@ type Account struct { TargetingPrefix string `mapstructure:"targeting_prefix" json:"targeting_prefix"` } -// CookieSync represents the account-level defaults for the cookie sync endpoint. -type CookieSync struct { - DefaultLimit *int `mapstructure:"default_limit" json:"default_limit"` - MaxLimit *int `mapstructure:"max_limit" json:"max_limit"` - DefaultCoopSync *bool `mapstructure:"default_coop_sync" json:"default_coop_sync"` - PriorityGroups [][]string `mapstructure:"priority_groups" json:"priority_groups"` +// AccountCookieSync represents the account-level defaults for the cookie sync endpoint. +type AccountCookieSync struct { + DefaultLimit *int `mapstructure:"default_limit" json:"default_limit"` + MaxLimit *int `mapstructure:"max_limit" json:"max_limit"` + DefaultCoopSync *bool `mapstructure:"default_coop_sync" json:"default_coop_sync"` + PriorityGroups [][]string `mapstructure:"priority_groups" json:"priority_groups"` + PriorityGroupsOnly *bool `mapstructure:"priority_groups_only" json:"priority_groups_only"` + DisabledIFrameBidders []string `mapstructure:"disabled_iframe_bidders" json:"disabled_iframe_bidders"` } // AccountCCPA represents account-specific CCPA configuration diff --git a/config/account_module_decoder.go b/config/account_module_decoder.go index 950460cc50..20d62e6de4 100644 --- a/config/account_module_decoder.go +++ b/config/account_module_decoder.go @@ -6,7 +6,7 @@ import ( "reflect" "github.com/mitchellh/mapstructure" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // AccountModulesHookFunc returns a mapstructure.DecodeHookFuncType that converts diff --git a/config/account_test.go b/config/account_test.go index 0e1d366caf..8e6d484724 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index 98cabd47df..e2455136b2 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -8,11 +8,11 @@ import ( "strings" "text/template" - "github.com/prebid/prebid-server/v3/logger" - "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/prebid/prebid-server/v3/util/sliceutil" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/sliceutil" validator "github.com/asaskevich/govalidator" "gopkg.in/yaml.v3" @@ -133,9 +133,6 @@ type Syncer struct { // ExternalURL is available as a macro to the RedirectURL template. ExternalURL string `yaml:"externalUrl" mapstructure:"external_url"` - // SupportCORS identifies if CORS is supported for the user syncing endpoints. - SupportCORS *bool `yaml:"supportCors" mapstructure:"support_cors"` - // FormatOverride allows a bidder to override their callback type "b" for iframe, "i" for redirect FormatOverride string `yaml:"formatOverride" mapstructure:"format_override"` @@ -160,7 +157,6 @@ func (s *Syncer) Equal(other *Syncer) bool { s.IFrame.Equal(other.IFrame) && s.Redirect.Equal(other.Redirect) && s.ExternalURL == other.ExternalURL && - ptrutil.Equal(s.SupportCORS, other.SupportCORS) && s.FormatOverride == other.FormatOverride && ptrutil.Equal(s.Enabled, other.Enabled) && s.SkipWhen.Equal(other.SkipWhen) @@ -277,7 +273,6 @@ func (s *Syncer) Defined() bool { s.IFrame != nil || s.Redirect != nil || s.ExternalURL != "" || - s.SupportCORS != nil || s.FormatOverride != "" || s.SkipWhen != nil } @@ -386,6 +381,9 @@ func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFi } parentBidderInfo := bidderInfos[aliasBidderInfo.AliasOf] + // Note: The aliasBidderInfo.GVLVendorID is intentionally never set to the parent's + // GVLVendorID. Each alias must declare its own GVL Vendor ID, as inheriting from the + // parent is not safe for legal reasons. if aliasBidderInfo.AppSecret == "" { aliasBidderInfo.AppSecret = parentBidderInfo.AppSecret } @@ -404,9 +402,6 @@ func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFi if aliasBidderInfo.ExtraAdapterInfo == "" { aliasBidderInfo.ExtraAdapterInfo = parentBidderInfo.ExtraAdapterInfo } - if aliasBidderInfo.GVLVendorID == 0 { - aliasBidderInfo.GVLVendorID = parentBidderInfo.GVLVendorID - } if aliasBidderInfo.Maintainer == nil { aliasBidderInfo.Maintainer = parentBidderInfo.Maintainer } @@ -477,17 +472,17 @@ func validateAliases(aliasBidderInfo BidderInfo, infos BidderInfos, bidderName s } if aliasBidderInfo.WhiteLabelOnly { - return fmt.Errorf("bidder: %s is an alias and cannot be set as white label only", bidderName) + return fmt.Errorf("bidder '%s' is an alias and cannot be set as white label only", bidderName) } parentBidder, parentBidderFound := infos[aliasBidderInfo.AliasOf] if !parentBidderFound { - return fmt.Errorf("bidder: %s not found for an alias: %s", aliasBidderInfo.AliasOf, bidderName) + return fmt.Errorf("alias '%s' references a nonexistent bidder '%s'", bidderName, aliasBidderInfo.AliasOf) } if len(parentBidder.AliasOf) > 0 { - return fmt.Errorf("bidder: %s cannot be an alias of an alias: %s", aliasBidderInfo.AliasOf, bidderName) + return fmt.Errorf("alias '%s' cannot reference another alias '%s'", bidderName, aliasBidderInfo.AliasOf) } return nil @@ -832,8 +827,8 @@ func (s *Syncer) Override(original *Syncer) *Syncer { copy.ExternalURL = s.ExternalURL } - if s.SupportCORS != nil { - copy.SupportCORS = s.SupportCORS + if s.Enabled != nil { + copy.Enabled = s.Enabled } return © diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index 8c251842c7..ac90a2de84 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -7,8 +7,8 @@ import ( "gopkg.in/yaml.v3" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -73,7 +73,6 @@ aliasOf: bidderA func TestLoadBidderInfoFromDisk(t *testing.T) { // should appear in result in mixed case bidder := "stroeerCore" - trueValue := true adapterConfigs := make(map[string]Adapter) adapterConfigs[strings.ToLower(bidder)] = Adapter{} @@ -115,7 +114,6 @@ func TestLoadBidderInfoFromDisk(t *testing.T) { ExternalURL: "https://redirect.host", UserMacro: "#UID", }, - SupportCORS: &trueValue, }, }, } @@ -255,7 +253,7 @@ func TestProcessBidderInfo(t *testing.T) { }, }, ExtraAdapterInfo: "extra-info", - GVLVendorID: 42, + GVLVendorID: 0, Maintainer: &MaintainerInfo{ Email: "some-email@domain.com", }, @@ -392,6 +390,7 @@ func TestProcessAliasBidderInfo(t *testing.T) { } bidderB := parentWithSyncerKey bidderB.AliasOf = "bidderA" + bidderB.GVLVendorID = 0 bidderB.Syncer = &Syncer{ Key: bidderB.Syncer.Key, } @@ -516,7 +515,7 @@ func TestProcessAliasBidderInfo(t *testing.T) { AliasOf: "bidderA", }, }, - expectedErr: errors.New("bidder: bidderA not found for an alias: bidderB"), + expectedErr: errors.New("alias 'bidderB' references a nonexistent bidder 'bidderA'"), }, { description: "bidder info not found for an alias", @@ -698,21 +697,21 @@ func TestValidateAliases(t *testing.T) { bidderName: "b", bidderInfo: BidderInfo{AliasOf: "nonexistent"}, bidderInfos: BidderInfos{}, - expectedErr: errors.New("bidder: nonexistent not found for an alias: b"), // does this make sense? should it be reversed? + expectedErr: errors.New("alias 'b' references a nonexistent bidder 'nonexistent'"), }, { name: "alias-of-alias", bidderName: "b", bidderInfo: BidderInfo{AliasOf: "a"}, bidderInfos: BidderInfos{"a": BidderInfo{AliasOf: "foo"}}, - expectedErr: errors.New("bidder: a cannot be an alias of an alias: b"), // does this make sense? should it be reversed? + expectedErr: errors.New("alias 'b' cannot reference another alias 'a'"), }, { name: "whitelabelonly", bidderName: "b", bidderInfo: BidderInfo{AliasOf: "a", WhiteLabelOnly: true}, bidderInfos: BidderInfos{"a": BidderInfo{}}, - expectedErr: errors.New("bidder: b is an alias and cannot be set as white label only"), + expectedErr: errors.New("bidder 'b' is an alias and cannot be set as white label only"), }, } @@ -1402,11 +1401,6 @@ func TestBidderInfoValidationNegative(t *testing.T) { } func TestSyncerOverride(t *testing.T) { - var ( - trueValue = true - falseValue = false - ) - testCases := []struct { description string givenOriginal *Syncer @@ -1467,18 +1461,36 @@ func TestSyncerOverride(t *testing.T) { givenOverride: &Syncer{ExternalURL: "override"}, expected: &Syncer{ExternalURL: "override"}, }, - { - description: "Override SupportCORS", - givenOriginal: &Syncer{SupportCORS: &trueValue}, - givenOverride: &Syncer{SupportCORS: &falseValue}, - expected: &Syncer{SupportCORS: &falseValue}, - }, { description: "Override Partial - Other Fields Untouched", givenOriginal: &Syncer{Key: "originalKey", ExternalURL: "originalExternalURL"}, givenOverride: &Syncer{ExternalURL: "overrideExternalURL"}, expected: &Syncer{Key: "originalKey", ExternalURL: "overrideExternalURL"}, }, + { + description: "Override Enabled - True To False", + givenOriginal: &Syncer{Key: "originalKey", Enabled: ptrutil.ToPtr(true)}, + givenOverride: &Syncer{Enabled: ptrutil.ToPtr(false)}, + expected: &Syncer{Key: "originalKey", Enabled: ptrutil.ToPtr(false)}, + }, + { + description: "Override Enabled - False To True", + givenOriginal: &Syncer{Key: "originalKey", Enabled: ptrutil.ToPtr(false)}, + givenOverride: &Syncer{Enabled: ptrutil.ToPtr(true)}, + expected: &Syncer{Key: "originalKey", Enabled: ptrutil.ToPtr(true)}, + }, + { + description: "Override Enabled - Nil Preserves Original", + givenOriginal: &Syncer{Key: "originalKey", Enabled: ptrutil.ToPtr(true)}, + givenOverride: &Syncer{}, + expected: &Syncer{Key: "originalKey", Enabled: ptrutil.ToPtr(true)}, + }, + { + description: "Override Enabled - Set On Nil Original", + givenOriginal: nil, + givenOverride: &Syncer{Enabled: ptrutil.ToPtr(false)}, + expected: &Syncer{Enabled: ptrutil.ToPtr(false)}, + }, } for _, test := range testCases { @@ -1715,18 +1727,6 @@ func TestSyncerEqual(t *testing.T) { }, expected: false, }, - { - name: "different-support-cors", - syncer1: &Syncer{ - Key: "key", - SupportCORS: ptrutil.ToPtr(true), - }, - syncer2: &Syncer{ - Key: "key", - SupportCORS: ptrutil.ToPtr(false), - }, - expected: false, - }, { name: "different-format-override", syncer1: &Syncer{ @@ -1782,7 +1782,6 @@ func TestSyncerEqual(t *testing.T) { UserMacro: "$UID", }, ExternalURL: "https://external.com", - SupportCORS: ptrutil.ToPtr(true), FormatOverride: "i", Enabled: ptrutil.ToPtr(true), SkipWhen: &SkipWhen{ @@ -1803,7 +1802,6 @@ func TestSyncerEqual(t *testing.T) { UserMacro: "$UID", }, ExternalURL: "https://external.com", - SupportCORS: ptrutil.ToPtr(true), FormatOverride: "i", Enabled: ptrutil.ToPtr(true), SkipWhen: &SkipWhen{ @@ -2073,11 +2071,6 @@ func TestSyncerDefined(t *testing.T) { givenSyncer: &Syncer{ExternalURL: "anyURL"}, expected: true, }, - { - name: "supportscors-only", - givenSyncer: &Syncer{SupportCORS: ptrutil.ToPtr(false)}, - expected: true, - }, { name: "formatoverride-only", givenSyncer: &Syncer{FormatOverride: "anyFormat"}, diff --git a/config/compression.go b/config/compression.go index c838e3390a..c99a893ca9 100644 --- a/config/compression.go +++ b/config/compression.go @@ -1,6 +1,6 @@ package config -import "github.com/prebid/prebid-server/v3/util/httputil" +import "github.com/prebid/prebid-server/v4/util/httputil" type Compression struct { Request CompressionInfo `mapstructure:"request"` diff --git a/config/compression_test.go b/config/compression_test.go index 78e7b6468e..23f4bb5fa4 100644 --- a/config/compression_test.go +++ b/config/compression_test.go @@ -3,7 +3,7 @@ package config import ( "testing" - "github.com/prebid/prebid-server/v3/util/httputil" + "github.com/prebid/prebid-server/v4/util/httputil" "github.com/stretchr/testify/assert" ) diff --git a/config/config.go b/config/config.go index 7550217d68..9a2fdee131 100644 --- a/config/config.go +++ b/config/config.go @@ -11,10 +11,10 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/spf13/viper" ) @@ -51,8 +51,12 @@ type Configuration struct { CategoryMapping StoredRequests `mapstructure:"category_mapping"` VTrack VTrack `mapstructure:"vtrack"` Event Event `mapstructure:"event"` + Video Video `mapstructure:"video"` Accounts StoredRequests `mapstructure:"accounts"` UserSync UserSync `mapstructure:"user_sync"` + // CookieSync holds host-level cookie sync settings that are always enforced and + // cannot be overridden by account configuration. + CookieSync CookieSync `mapstructure:"cookie_sync"` // Note that StoredVideo refers to stored video requests, and has nothing to do with caching video creatives. StoredVideo StoredRequests `mapstructure:"stored_video_req"` StoredResponses StoredRequests `mapstructure:"stored_responses"` @@ -80,8 +84,6 @@ type Configuration struct { AccountDefaults Account `mapstructure:"account_defaults"` // accountDefaultsJSON is the internal serialized form of AccountDefaults used for json merge accountDefaultsJSON json.RawMessage - // CertsUseSystem will use the host OS certificates instead of embedded certs. - CertsUseSystem bool `mapstructure:"certificates_use_system"` // Local private file containing SSL certificates PemCertsFile string `mapstructure:"certificates_file"` // Custom headers to handle request timeouts from queueing infrastructure @@ -275,6 +277,7 @@ type GDPR struct { NonStandardPublisherMap map[string]struct{} TCF2 TCF2 `mapstructure:"tcf2"` AMPException bool `mapstructure:"amp_exception"` // Deprecated: Use account-level GDPR settings (gdpr.integration_enabled.amp) instead + LiveGVLRefreshInterval int `mapstructure:"live_gvl_refresh_interval_seconds"` // EEACountries (EEA = European Economic Area) are a list of countries where we should assume GDPR applies. // If the gdpr flag is unset in a request, but geo.country is set, we will assume GDPR applies if and only // if the country matches one on this list. If both the GDPR flag and country are not set, we default @@ -557,6 +560,10 @@ type Event struct { TimeoutMS int64 `mapstructure:"timeout_ms"` } +type Video struct { + EnableDeprecatedEndpoint bool `mapstructure:"enable_deprecated_endpoint"` +} + type HostCookie struct { Domain string `mapstructure:"domain"` Family string `mapstructure:"family"` @@ -606,7 +613,7 @@ type DisabledMetrics struct { AdapterConnectionMetrics bool `mapstructure:"adapter_connections_metrics"` // True if we don't want to collect metrics on dial time and dial errors - AdapterConnectionDialMetrics bool `mapstructure:"adapter_connection_dial_metrics"` + AdapterConnectionDialMetrics bool `mapstructure:"adapter_connections_dial_metrics"` // True if we don't want to collect the per adapter buyer UID scrubbed metric AdapterBuyerUIDScrubbed bool `mapstructure:"adapter_buyeruid_scrubbed"` @@ -1010,7 +1017,7 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("metrics.disabled_metrics.account_debug", true) v.SetDefault("metrics.disabled_metrics.account_stored_responses", true) v.SetDefault("metrics.disabled_metrics.adapter_connections_metrics", true) - v.SetDefault("metrics.disabled_metrics.adapter_connection_dial_metrics", true) + v.SetDefault("metrics.disabled_metrics.adapter_connections_dial_metrics", true) v.SetDefault("metrics.disabled_metrics.adapter_buyeruid_scrubbed", true) v.SetDefault("metrics.disabled_metrics.adapter_gdpr_request_blocked", false) v.SetDefault("metrics.influxdb.host", "") @@ -1052,7 +1059,7 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("stored_requests.directorypath", "./stored_requests/data/by_id") v.SetDefault("stored_requests.http.endpoint", "") v.SetDefault("stored_requests.http.amp_endpoint", "") - v.SetDefault("stored_requests.http.use_rfc3986_compliant_request_builder", false) + v.SetDefault("stored_requests.http.use_rfc3986_compliant_request_builder", true) v.SetDefault("stored_requests.in_memory_cache.type", "none") v.SetDefault("stored_requests.in_memory_cache.ttl_seconds", 0) v.SetDefault("stored_requests.in_memory_cache.request_cache_size_bytes", 0) @@ -1136,12 +1143,14 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("event.timeout_ms", 1000) + v.SetDefault("video.enable_deprecated_endpoint", false) + v.SetDefault("user_sync.priority_groups", [][]string{}) v.SetDefault("accounts.filesystem.enabled", false) v.SetDefault("accounts.filesystem.directorypath", "./stored_requests/data/by_id") v.SetDefault("accounts.http.endpoint", "") - v.SetDefault("accounts.http.use_rfc3986_compliant_request_builder", false) + v.SetDefault("accounts.http.use_rfc3986_compliant_request_builder", true) v.SetDefault("accounts.in_memory_cache.type", "none") v.SetDefault("accounts.in_memory_cache.ttl_seconds", 0) v.SetDefault("accounts.in_memory_cache.size_bytes", 0) @@ -1182,6 +1191,7 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("gdpr.timeouts_ms.init_vendorlist_fetches", 0) v.SetDefault("gdpr.timeouts_ms.active_vendorlist_fetch", 0) v.SetDefault("gdpr.non_standard_publishers", []string{""}) + v.SetDefault("gdpr.live_gvl_refresh_interval_seconds", 86400) // 1 day v.SetDefault("gdpr.tcf2.enabled", true) v.SetDefault("gdpr.tcf2.purpose1.enforce_vendors", true) v.SetDefault("gdpr.tcf2.purpose2.enforce_vendors", true) @@ -1264,7 +1274,6 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("compression.response.enable_gzip", false) v.SetDefault("compression.request.enable_gzip", false) - v.SetDefault("certificates_use_system", false) v.SetDefault("certificates_file", "") v.SetDefault("auto_gen_source_tid", true) @@ -1386,6 +1395,7 @@ func setBidderDefaults(v *viper.Viper, bidder string) { v.BindEnv(adapterCfgPrefix + ".openrtb.version") v.BindEnv(adapterCfgPrefix + ".openrtb.gpp-supported") + v.BindEnv(adapterCfgPrefix + ".usersync.enabled") v.BindEnv(adapterCfgPrefix + ".usersync.key") v.BindEnv(adapterCfgPrefix + ".usersync.default") v.BindEnv(adapterCfgPrefix + ".usersync.iframe.url") diff --git a/config/config_test.go b/config/config_test.go index 3d7a0408b3..6bb206f41f 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/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/spf13/viper" "github.com/stretchr/testify/assert" ) @@ -158,7 +158,7 @@ func TestDefaults(t *testing.T) { cmpBools(t, "account_debug", true, cfg.Metrics.Disabled.AccountDebug) cmpBools(t, "account_stored_responses", true, cfg.Metrics.Disabled.AccountStoredResponses) cmpBools(t, "adapter_connections_metrics", true, cfg.Metrics.Disabled.AdapterConnectionMetrics) - cmpBools(t, "adapter_connection_dial_metrics", true, cfg.Metrics.Disabled.AdapterConnectionDialMetrics) + cmpBools(t, "adapter_connections_dial_metrics", true, cfg.Metrics.Disabled.AdapterConnectionDialMetrics) cmpBools(t, "adapter_buyeruid_scrubbed", true, cfg.Metrics.Disabled.AdapterBuyerUIDScrubbed) cmpBools(t, "adapter_gdpr_request_blocked", false, cfg.Metrics.Disabled.AdapterGDPRRequestBlocked) cmpStrings(t, "certificates_file", "", cfg.PemCertsFile) @@ -167,11 +167,12 @@ func TestDefaults(t *testing.T) { cmpStrings(t, "stored_requests.filesystem.directorypath", "./stored_requests/data/by_id", cfg.StoredRequests.Files.Path) cmpStrings(t, "stored_requests.http.endpoint", "", cfg.StoredRequests.HTTP.Endpoint) cmpStrings(t, "stored_requests.http.amp_endpoint", "", cfg.StoredRequests.HTTP.AmpEndpoint) - cmpBools(t, "stored_requests.http.use_rfc3986_compliant_request_builder", false, cfg.StoredRequests.HTTP.UseRfcCompliantBuilder) + cmpBools(t, "stored_requests.http.use_rfc3986_compliant_request_builder", true, cfg.StoredRequests.HTTP.UseRfcCompliantBuilder) + cmpBools(t, "video.enable_deprecated_endpoint", false, cfg.Video.EnableDeprecatedEndpoint) cmpBools(t, "accounts.filesystem.enabled", false, cfg.Accounts.Files.Enabled) cmpStrings(t, "accounts.filesystem.directorypath", "./stored_requests/data/by_id", cfg.Accounts.Files.Path) cmpStrings(t, "accounts.http.endpoint", "", cfg.Accounts.HTTP.Endpoint) - cmpBools(t, "accounts.http.use_rfc3986_compliant_request_builder", false, cfg.Accounts.HTTP.UseRfcCompliantBuilder) + cmpBools(t, "accounts.http.use_rfc3986_compliant_request_builder", true, cfg.Accounts.HTTP.UseRfcCompliantBuilder) cmpStrings(t, "accounts.in_memory_cache.type", "none", cfg.Accounts.InMemoryCache.Type) cmpInts(t, "accounts.in_memory_cache.ttl_seconds", 0, cfg.Accounts.InMemoryCache.TTL) cmpInts(t, "accounts.in_memory_cache.size_bytes", 0, cfg.Accounts.InMemoryCache.Size) @@ -254,6 +255,7 @@ func TestDefaults(t *testing.T) { cmpInts(t, "analytics.agma.buffers.count", 100, cfg.Analytics.Agma.Buffers.EventCount) cmpStrings(t, "analytics.agma.buffers.timeout", "15m", cfg.Analytics.Agma.Buffers.Timeout) cmpInts(t, "analytics.agma.accounts", 0, len(cfg.Analytics.Agma.Accounts)) + cmpInts(t, "gdpr.live_gvl_refresh_interval_seconds", 86400, cfg.GDPR.LiveGVLRefreshInterval) expectedTCF2 := TCF2{ Enabled: true, Purpose1: TCF2Purpose{ @@ -369,7 +371,7 @@ accounts: directorypath: "./example_directory" http: endpoint: "https://prebid.org" - use_rfc3986_compliant_request_builder: true + use_rfc3986_compliant_request_builder: false in_memory_cache: type: "lru" ttl_seconds: 300 @@ -386,6 +388,7 @@ gdpr: default_value: "1" non_standard_publishers: ["pub1", "pub2"] eea_countries: ["eea1", "eea2"] + live_gvl_refresh_interval_seconds: 3600 tcf2: purpose1: enforce_vendors: false @@ -422,10 +425,14 @@ gdpr: vendor_exceptions: ["foo10"] special_feature1: vendor_exceptions: ["fooSP1"] +video: + enable_deprecated_endpoint: true ccpa: enforce: true lmt: enforce: true +cookie_sync: + disabled_iframe_bidders: ["hostBidder1", "hostBidder2"] host_cookie: cookie_name: userid family: prebid @@ -484,7 +491,7 @@ metrics: account_debug: false account_stored_responses: false adapter_connections_metrics: true - adapter_connection_dial_metrics: true + adapter_connections_dial_metrics: true adapter_buyeruid_scrubbed: false adapter_gdpr_request_blocked: true account_modules_metrics: true @@ -600,7 +607,6 @@ analytics: - code: agma-code publisher_id: publisher-id site_app_id: site-or-app-id -certificates_use_system: true `) func cmpStrings(t *testing.T, key, expected, actual string) { @@ -647,6 +653,7 @@ func TestFullConfig(t *testing.T) { cmpStrings(t, "cookie family", "prebid", cfg.HostCookie.Family) cmpStrings(t, "opt out", "http://prebid.org/optout", cfg.HostCookie.OptOutURL) cmpStrings(t, "opt in", "http://prebid.org/optin", cfg.HostCookie.OptInURL) + assert.Equal(t, []string{"hostBidder1", "hostBidder2"}, cfg.CookieSync.DisabledIFrameBidders, "cookie_sync.disabled_iframe_bidders") cmpStrings(t, "external url", "http://prebid-server.prebid.org/", cfg.ExternalURL) cmpStrings(t, "host", "prebid-server.prebid.org", cfg.Host) cmpInts(t, "port", 1234, cfg.Port) @@ -657,11 +664,11 @@ func TestFullConfig(t *testing.T) { cmpInts(t, "stored_request_timeout_ms", 75, cfg.StoredRequestsTimeout) cmpStrings(t, "stored_requests.http.endpoint", "", cfg.StoredRequests.HTTP.Endpoint) cmpStrings(t, "stored_requests.http.amp_endpoint", "", cfg.StoredRequests.HTTP.AmpEndpoint) - cmpBools(t, "stored_requests.http.use_rfc3986_compliant_request_builder", false, cfg.StoredRequests.HTTP.UseRfcCompliantBuilder) + cmpBools(t, "stored_requests.http.use_rfc3986_compliant_request_builder", true, cfg.StoredRequests.HTTP.UseRfcCompliantBuilder) cmpBools(t, "accounts.filesystem.enabled", true, cfg.Accounts.Files.Enabled) cmpStrings(t, "accounts.filesystem.directorypath", "./example_directory", cfg.Accounts.Files.Path) cmpStrings(t, "accounts.http.endpoint", "https://prebid.org", cfg.Accounts.HTTP.Endpoint) - cmpBools(t, "accounts.http.use_rfc3986_compliant_request_builder", true, cfg.Accounts.HTTP.UseRfcCompliantBuilder) + cmpBools(t, "accounts.http.use_rfc3986_compliant_request_builder", false, cfg.Accounts.HTTP.UseRfcCompliantBuilder) cmpStrings(t, "accounts.in_memory_cache.type", "lru", cfg.Accounts.InMemoryCache.Type) cmpInts(t, "accounts.in_memory_cache.ttl_seconds", 300, cfg.Accounts.InMemoryCache.TTL) cmpInts(t, "accounts.in_memory_cache.size_bytes", 1000, cfg.Accounts.InMemoryCache.Size) @@ -686,6 +693,8 @@ func TestFullConfig(t *testing.T) { cmpInts(t, "http_client_cache.idle_connection_timeout_seconds", 3, cfg.CacheClient.IdleConnTimeout) cmpInts(t, "gdpr.host_vendor_id", 15, cfg.GDPR.HostVendorID) cmpStrings(t, "gdpr.default_value", "1", cfg.GDPR.DefaultValue) + cmpInts(t, "gdpr.live_gvl_refresh_interval_seconds", 3600, cfg.GDPR.LiveGVLRefreshInterval) + cmpBools(t, "video.enable_deprecated_endpoint", true, cfg.Video.EnableDeprecatedEndpoint) cmpStrings(t, "host_schain_node.asi", "pbshostcompany.com", cfg.HostSChainNode.ASI) cmpStrings(t, "host_schain_node.sid", "00001", cfg.HostSChainNode.SID) cmpStrings(t, "host_schain_node.rid", "BidRequest", cfg.HostSChainNode.RID) @@ -921,7 +930,7 @@ func TestFullConfig(t *testing.T) { cmpBools(t, "account_debug", false, cfg.Metrics.Disabled.AccountDebug) cmpBools(t, "account_stored_responses", false, cfg.Metrics.Disabled.AccountStoredResponses) cmpBools(t, "adapter_connections_metrics", true, cfg.Metrics.Disabled.AdapterConnectionMetrics) - cmpBools(t, "adapter_connection_dial_metrics", true, cfg.Metrics.Disabled.AdapterConnectionDialMetrics) + cmpBools(t, "adapter_connections_dial_metrics", true, cfg.Metrics.Disabled.AdapterConnectionDialMetrics) cmpBools(t, "adapter_buyeruid_scrubbed", false, cfg.Metrics.Disabled.AdapterBuyerUIDScrubbed) cmpBools(t, "adapter_gdpr_request_blocked", true, cfg.Metrics.Disabled.AdapterGDPRRequestBlocked) cmpStrings(t, "certificates_file", "/etc/ssl/cert.pem", cfg.PemCertsFile) @@ -949,7 +958,6 @@ func TestFullConfig(t *testing.T) { cmpStrings(t, "analytics.agma.accounts.0.publisher_id", "publisher-id", cfg.Analytics.Agma.Accounts[0].PublisherId) cmpStrings(t, "analytics.agma.accounts.0.code", "agma-code", cfg.Analytics.Agma.Accounts[0].Code) cmpStrings(t, "analytics.agma.accounts.0.site_app_id", "site-or-app-id", cfg.Analytics.Agma.Accounts[0].SiteAppId) - cmpBools(t, "certificates_use_system", true, cfg.CertsUseSystem) } func TestValidateConfig(t *testing.T) { @@ -1021,8 +1029,6 @@ func TestMigrateConfigFromEnv(t *testing.T) { } func TestUserSyncFromEnv(t *testing.T) { - truePtr := true - // setup env vars for testing if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_URL"); ok { defer os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_URL", oldval) @@ -1048,22 +1054,28 @@ func TestUserSyncFromEnv(t *testing.T) { defer os.Unsetenv("PBS_ADAPTERS_BIDDER2_USERSYNC_IFRAME_URL") } + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER2_USERSYNC_ENABLED"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER2_USERSYNC_ENABLED", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER2_USERSYNC_ENABLED") + } + // set new os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_URL", "http://some.url/sync?redirect={{.RedirectURL}}") os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_USER_MACRO", "[UID]") os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_SUPPORT_CORS", "true") os.Setenv("PBS_ADAPTERS_BIDDER2_USERSYNC_IFRAME_URL", "http://somedifferent.url/sync?redirect={{.RedirectURL}}") + os.Setenv("PBS_ADAPTERS_BIDDER2_USERSYNC_ENABLED", "false") cfg, _ := newDefaultConfig(t) assert.Equal(t, "http://some.url/sync?redirect={{.RedirectURL}}", cfg.BidderInfos["bidder1"].Syncer.Redirect.URL) assert.Equal(t, "[UID]", cfg.BidderInfos["bidder1"].Syncer.Redirect.UserMacro) assert.Nil(t, cfg.BidderInfos["bidder1"].Syncer.IFrame) - assert.Equal(t, &truePtr, cfg.BidderInfos["bidder1"].Syncer.SupportCORS) assert.Equal(t, "http://somedifferent.url/sync?redirect={{.RedirectURL}}", cfg.BidderInfos["bidder2"].Syncer.IFrame.URL) assert.Nil(t, cfg.BidderInfos["bidder2"].Syncer.Redirect) - assert.Nil(t, cfg.BidderInfos["bidder2"].Syncer.SupportCORS) + assert.Equal(t, ptrutil.ToPtr(false), cfg.BidderInfos["bidder2"].Syncer.Enabled) } func TestBidderInfoFromEnv(t *testing.T) { diff --git a/config/stored_requests.go b/config/stored_requests.go index 73acc1bf06..92eab4ea8e 100644 --- a/config/stored_requests.go +++ b/config/stored_requests.go @@ -5,7 +5,7 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/v3/logger" + "github.com/prebid/prebid-server/v4/logger" ) // DataType constants diff --git a/config/structlog.go b/config/structlog.go index 6faec25cc5..d89af631e5 100644 --- a/config/structlog.go +++ b/config/structlog.go @@ -6,7 +6,7 @@ import ( "regexp" "strings" - logInternal "github.com/prebid/prebid-server/v3/logger" + logInternal "github.com/prebid/prebid-server/v4/logger" ) type logMsg func(string, ...interface{}) @@ -37,6 +37,10 @@ func logGeneralWithLogger(v reflect.Value, prefix string, logger logMsg) { logger("%s: %f", prefix, v.Float()) case reflect.Bool: logger("%s: %t", prefix, v.Bool()) + case reflect.Ptr: + if v.Elem().IsValid() { + logGeneralWithLogger(v.Elem(), prefix, logger) + } default: // logString, by using v.String(), will not fail, and indicate what additional cases we need to handle logger("%s: %s", prefix, v.String()) @@ -45,7 +49,7 @@ func logGeneralWithLogger(v reflect.Value, prefix string, logger logMsg) { func logStructWithLogger(v reflect.Value, prefix string, logger logMsg) { if v.Kind() != reflect.Struct { - logInternal.Fatalf("LogStruct called on type %s, whuch is not a struct!", v.Type().String()) + logInternal.Fatalf("LogStruct called on type %s, which is not a struct!", v.Type().String()) } t := v.Type() for i := 0; i < t.NumField(); i++ { @@ -60,7 +64,7 @@ func logStructWithLogger(v reflect.Value, prefix string, logger logMsg) { func logMapWithLogger(v reflect.Value, prefix string, logger logMsg) { if v.Kind() != reflect.Map { - logInternal.Fatalf("LogMap called on type %s, whuch is not a map!", v.Type().String()) + logInternal.Fatalf("LogMap called on type %s, which is not a map!", v.Type().String()) } for _, k := range v.MapKeys() { if k.Kind() == reflect.String && !allowedName(k.String()) { diff --git a/config/structlog_test.go b/config/structlog_test.go index d7ed720c73..d0e3c91da9 100644 --- a/config/structlog_test.go +++ b/config/structlog_test.go @@ -8,11 +8,13 @@ import ( ) type testStruct struct { - Myint int `mapstructure:"this_int"` - Mystring string `mapstructure:"mystring"` - Flag bool - Sub innerStruct `mapstructure:"sub"` - Caps map[string]string + Myint int `mapstructure:"this_int"` + Mystring string `mapstructure:"mystring"` + Flag bool + Sub innerStruct `mapstructure:"sub"` + Caps map[string]string + NestedStruct *nestedStruct + NillableStruct *nestedStruct } type innerStruct struct { @@ -20,12 +22,17 @@ type innerStruct struct { password string `mapstructure:"password"` } +type nestedStruct struct { + var1 string +} + var expected string = `this_int: 5 mystring: foobar ((Flag)): false sub.int1: 3 sub.password: ((Caps))[Alabama]: Montgomery +((NestedStruct)).((var1)): abc ` func TestBasic(t *testing.T) { @@ -46,6 +53,8 @@ func TestBasic(t *testing.T) { Caps: map[string]string{ "Alabama": "Montgomery", }, + NestedStruct: &nestedStruct{var1: "abc"}, + NillableStruct: nil, } logStructWithLogger(reflect.ValueOf(testCfg), "", mylogger) diff --git a/config/test/bidder-info-valid/stroeerCore.yaml b/config/test/bidder-info-valid/stroeerCore.yaml index ef95d2388a..47314187ba 100644 --- a/config/test/bidder-info-valid/stroeerCore.yaml +++ b/config/test/bidder-info-valid/stroeerCore.yaml @@ -27,5 +27,4 @@ userSync: url: "https://foo.com/sync?mode=redirect&r={{.RedirectURL}}" redirectUrl: "{{.ExternalURL}}/setuid/redirect" externalUrl: "https://redirect.host" - userMacro: "#UID" - supportCors: true \ No newline at end of file + userMacro: "#UID" \ No newline at end of file diff --git a/config/usersync.go b/config/usersync.go index d490853d08..7fed692cef 100644 --- a/config/usersync.go +++ b/config/usersync.go @@ -12,3 +12,12 @@ type UserSync struct { type UserSyncCooperative struct { EnabledByDefault bool `mapstructure:"default"` } + +// CookieSync specifies host-level cookie sync settings that are always enforced by the +// host operator. These settings cannot be overridden by account configuration and are +// unioned with any account-level restrictions. +type CookieSync struct { + // DisabledIFrameBidders lists bidders for which iframe cookie syncs are disabled for + // every account. Use "*" to disable iframe syncs for all bidders. + DisabledIFrameBidders []string `mapstructure:"disabled_iframe_bidders" json:"disabled_iframe_bidders"` +} diff --git a/currency/currency.go b/currency/currency.go index b4d886274e..236c2235db 100644 --- a/currency/currency.go +++ b/currency/currency.go @@ -1,7 +1,7 @@ package currency import ( - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func GetAuctionCurrencyRates(currencyConverter *RateConverter, requestRates *openrtb_ext.ExtRequestCurrency) Conversions { diff --git a/currency/currency_test.go b/currency/currency_test.go index c29c8d18e7..f8ceb3ac27 100644 --- a/currency/currency_test.go +++ b/currency/currency_test.go @@ -4,9 +4,9 @@ import ( "testing" "time" - "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/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/currency/rate_converter.go b/currency/rate_converter.go index c791c9b665..ba7639df9b 100644 --- a/currency/rate_converter.go +++ b/currency/rate_converter.go @@ -8,10 +8,10 @@ import ( "sync/atomic" "time" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/util/jsonutil" - "github.com/prebid/prebid-server/v3/util/timeutil" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/timeutil" ) // RateConverter holds the currencies conversion rates dictionary diff --git a/currency/rate_converter_test.go b/currency/rate_converter_test.go index 0698a7ba27..c218128dda 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/v3/util/task" + "github.com/prebid/prebid-server/v4/util/task" "github.com/stretchr/testify/assert" ) diff --git a/currency/rates_test.go b/currency/rates_test.go index 555d299d21..f922fa62a9 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/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" "golang.org/x/text/currency" ) diff --git a/currency/validation.go b/currency/validation.go index 5e23362e5b..45b2522a59 100644 --- a/currency/validation.go +++ b/currency/validation.go @@ -5,8 +5,8 @@ import ( "golang.org/x/text/currency" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/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 0edd5c89a3..fd22c2efd2 100644 --- a/currency/validation_test.go +++ b/currency/validation_test.go @@ -3,8 +3,8 @@ package currency import ( "testing" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/dsa/validate.go b/dsa/validate.go index 3dce2fba1c..09f97456f4 100644 --- a/dsa/validate.go +++ b/dsa/validate.go @@ -3,9 +3,9 @@ package dsa import ( "errors" - "github.com/prebid/prebid-server/v3/exchange/entities" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // Required values representing whether a DSA object is required diff --git a/dsa/validate_test.go b/dsa/validate_test.go index e0af9bc80a..104ef1154c 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/v3/exchange/entities" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/dsa/writer.go b/dsa/writer.go index 33d0bda6d3..9e5d164e76 100644 --- a/dsa/writer.go +++ b/dsa/writer.go @@ -1,8 +1,8 @@ package dsa import ( - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/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 bbe82e0b69..04826c408a 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/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index a90bc6117d..27ba40f0e8 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -8,6 +8,7 @@ import ( "io" "math" "net/http" + "slices" "strconv" "strings" "time" @@ -15,23 +16,24 @@ import ( "github.com/julienschmidt/httprouter" gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" - 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/logger" - "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" + accountService "github.com/prebid/prebid-server/v4/account" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/privacy/ccpa" + gppPrivacy "github.com/prebid/prebid-server/v4/privacy/gpp" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/usersync" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" + stringutil "github.com/prebid/prebid-server/v4/util/stringutil" + "github.com/prebid/prebid-server/v4/util/timeutil" ) const receiveCookieDeprecation = "receive-cookie-deprecation" @@ -167,6 +169,9 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, ma return usersync.Request{}, macros.UserSyncPrivacy{}, account, err } + disabledIFrameBidders := mergeDisabledIFrameBidders(c.config.CookieSync.DisabledIFrameBidders, account.CookieSync.DisabledIFrameBidders) + syncTypeFilter = applyDisabledIFrameBidders(syncTypeFilter, disabledIFrameBidders) + gdprRequestInfo := gdpr.RequestInfo{ Consent: privacyMacros.GDPRConsent, GDPRSignal: gdprSignal, @@ -183,8 +188,9 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, ma rx := usersync.Request{ Bidders: request.Bidders, Cooperative: usersync.Cooperative{ - Enabled: (request.CooperativeSync != nil && *request.CooperativeSync) || (request.CooperativeSync == nil && c.config.UserSync.Cooperative.EnabledByDefault), - PriorityGroups: c.findPriorityGroups(account.CookieSync), + Enabled: (request.CooperativeSync != nil && *request.CooperativeSync) || (request.CooperativeSync == nil && c.config.UserSync.Cooperative.EnabledByDefault), + PriorityGroups: c.findPriorityGroups(account.CookieSync), + PriorityGroupsOnly: ptrutil.ValueOrDefault(account.CookieSync.PriorityGroupsOnly), }, Debug: request.Debug, Limit: limit, @@ -290,7 +296,7 @@ func (c *cookieSyncEndpoint) writeParseRequestErrorMetrics(err error) { } } -func (c *cookieSyncEndpoint) setLimit(request cookieSyncRequest, cookieSyncConfig config.CookieSync) cookieSyncRequest { +func (c *cookieSyncEndpoint) setLimit(request cookieSyncRequest, cookieSyncConfig config.AccountCookieSync) cookieSyncRequest { limit := getEffectiveLimit(request.Limit, cookieSyncConfig.DefaultLimit) maxLimit := getEffectiveMaxLimit(cookieSyncConfig.MaxLimit) if maxLimit < limit { @@ -325,7 +331,7 @@ func getEffectiveMaxLimit(maxLimit *int) int { return math.MaxInt } -func (c *cookieSyncEndpoint) setCooperativeSync(request cookieSyncRequest, cookieSyncConfig config.CookieSync) cookieSyncRequest { +func (c *cookieSyncEndpoint) setCooperativeSync(request cookieSyncRequest, cookieSyncConfig config.AccountCookieSync) cookieSyncRequest { if request.CooperativeSync == nil && cookieSyncConfig.DefaultCoopSync != nil { request.CooperativeSync = cookieSyncConfig.DefaultCoopSync } @@ -333,7 +339,7 @@ func (c *cookieSyncEndpoint) setCooperativeSync(request cookieSyncRequest, cooki return request } -func (c *cookieSyncEndpoint) findPriorityGroups(accountCookieSyncConfig config.CookieSync) [][]string { +func (c *cookieSyncEndpoint) findPriorityGroups(accountCookieSyncConfig config.AccountCookieSync) [][]string { // Account-level config takes precedence over global config, which will be deprecated in the future if accountCookieSyncConfig.DefaultCoopSync != nil { return accountCookieSyncConfig.PriorityGroups @@ -341,6 +347,60 @@ func (c *cookieSyncEndpoint) findPriorityGroups(accountCookieSyncConfig config.C return c.config.UserSync.PriorityGroups } +// mergeDisabledIFrameBidders returns the union of the host-level and account-level +// disabled iframe bidder lists. Host-level entries are always enforced and cannot be +// overridden by account configuration. Duplicates are removed while preserving order, +// with host entries taking precedence. +func mergeDisabledIFrameBidders(host, account []string) []string { + if len(host) == 0 { + return account + } + if len(account) == 0 { + return host + } + + merged := make([]string, 0, len(host)+len(account)) + seen := make(map[string]struct{}, len(host)+len(account)) + for _, bidder := range host { + if _, ok := seen[bidder]; !ok { + seen[bidder] = struct{}{} + merged = append(merged, bidder) + } + } + for _, bidder := range account { + if _, ok := seen[bidder]; !ok { + seen[bidder] = struct{}{} + merged = append(merged, bidder) + } + } + return merged +} + +// applyDisabledIFrameBidders enforces iframe cookie sync restrictions from the union of +// host-level and account-level configuration. +// The disabledIFrameBidders slice supports two formats, matching the filterSettings convention: +// - "*" (string): disables iframe syncs for all bidders +// - ["bidderA", "bidderB"] (array): disables iframe syncs for specific bidders only +// When specific bidders are disabled, a CompositeFilter ANDs the request-level filter with the +// configured filter, ensuring configuration can only further restrict — never broaden — +// what the request's filterSettings allows. Redirect syncs are never affected. +func applyDisabledIFrameBidders(syncTypeFilter usersync.SyncTypeFilter, disabledIFrameBidders []string) usersync.SyncTypeFilter { + if len(disabledIFrameBidders) == 0 { + return syncTypeFilter + } + + if slices.Contains(disabledIFrameBidders, "*") { + syncTypeFilter.IFrame = usersync.NewUniformBidderFilter(usersync.BidderFilterModeExclude) + } else { + syncTypeFilter.IFrame = usersync.CompositeFilter{ + RequestFilter: syncTypeFilter.IFrame, + AccountFilter: usersync.NewSpecificBidderFilter(disabledIFrameBidders, usersync.BidderFilterModeExclude), + } + } + + return syncTypeFilter +} + func parseTypeFilter(request *cookieSyncRequestFilterSettings) (usersync.SyncTypeFilter, error) { syncTypeFilter := usersync.SyncTypeFilter{ IFrame: cookieSyncBidderFilterAllowAll, @@ -466,9 +526,8 @@ func (c *cookieSyncEndpoint) handleResponse(w http.ResponseWriter, tf usersync.S BidderCode: syncerChoice.Bidder, NoCookie: true, UsersyncInfo: cookieSyncResponseSync{ - URL: sync.URL, - Type: string(sync.Type), - SupportCORS: sync.SupportCORS, + URL: sync.URL, + Type: string(sync.Type), }, }) } @@ -536,9 +595,8 @@ func mapBidderStatusToAnalytics(from []cookieSyncResponseBidder) []*analytics.Co BidderCode: b.BidderCode, NoCookie: b.NoCookie, UsersyncInfo: &analytics.UsersyncInfo{ - URL: b.UsersyncInfo.URL, - Type: b.UsersyncInfo.Type, - SupportCORS: b.UsersyncInfo.SupportCORS, + URL: b.UsersyncInfo.URL, + Type: b.UsersyncInfo.Type, }, } } @@ -604,9 +662,8 @@ type cookieSyncResponseBidder struct { } type cookieSyncResponseSync struct { - URL string `json:"url,omitempty"` - Type string `json:"type,omitempty"` - SupportCORS bool `json:"supportCORS,omitempty"` + URL string `json:"url,omitempty"` + Type string `json:"type,omitempty"` } type cookieSyncResponseDebug struct { diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 6fc56f797b..5c022895a0 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -15,17 +15,17 @@ import ( "testing/iotest" "time" - "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/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/privacy/ccpa" + "github.com/prebid/prebid-server/v4/usersync" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -114,7 +114,7 @@ func TestNewCookieSyncEndpoint(t *testing.T) { func TestCookieSyncHandle(t *testing.T) { syncTypeExpected := []usersync.SyncType{usersync.SyncTypeIFrame, usersync.SyncTypeRedirect} - sync := usersync.Sync{URL: "aURL", Type: usersync.SyncTypeRedirect, SupportCORS: true} + sync := usersync.Sync{URL: "aURL", Type: usersync.SyncTypeRedirect} syncer := MockSyncer{} syncer.On("GetSync", syncTypeExpected, macros.UserSyncPrivacy{}).Return(sync, nil).Maybe() @@ -144,7 +144,7 @@ func TestCookieSyncHandle(t *testing.T) { }, expectedStatusCode: 200, expectedBody: `{"status":"ok","bidder_status":[` + - `{"bidder":"a","no_cookie":true,"usersync":{"url":"aURL","type":"redirect","supportCORS":true}}` + + `{"bidder":"a","no_cookie":true,"usersync":{"url":"aURL","type":"redirect"}}` + `]}` + "\n", setMetricsExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordCookieSync", metrics.CookieSyncOK).Once() @@ -158,7 +158,7 @@ func TestCookieSyncHandle(t *testing.T) { { BidderCode: "a", NoCookie: true, - UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "redirect", SupportCORS: true}, + UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "redirect"}, }, }, } @@ -176,7 +176,7 @@ func TestCookieSyncHandle(t *testing.T) { }, expectedStatusCode: 200, expectedBody: `{"status":"no_cookie","bidder_status":[` + - `{"bidder":"a","no_cookie":true,"usersync":{"url":"aURL","type":"redirect","supportCORS":true}}` + + `{"bidder":"a","no_cookie":true,"usersync":{"url":"aURL","type":"redirect"}}` + `]}` + "\n", setMetricsExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordCookieSync", metrics.CookieSyncOK).Once() @@ -190,7 +190,7 @@ func TestCookieSyncHandle(t *testing.T) { { BidderCode: "a", NoCookie: true, - UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "redirect", SupportCORS: true}, + UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "redirect"}, }, }, } @@ -277,7 +277,7 @@ func TestCookieSyncHandle(t *testing.T) { }, expectedStatusCode: 200, expectedBody: `{"status":"ok","bidder_status":[` + - `{"bidder":"a","no_cookie":true,"usersync":{"url":"aURL","type":"redirect","supportCORS":true}}` + + `{"bidder":"a","no_cookie":true,"usersync":{"url":"aURL","type":"redirect"}}` + `],"debug":[{"bidder":"a","error":"Already in sync"}]}` + "\n", setMetricsExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordCookieSync", metrics.CookieSyncOK).Once() @@ -291,7 +291,7 @@ func TestCookieSyncHandle(t *testing.T) { { BidderCode: "a", NoCookie: true, - UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "redirect", SupportCORS: true}, + UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "redirect"}, }, }, } @@ -313,7 +313,7 @@ func TestCookieSyncHandle(t *testing.T) { expectedStatusCode: 200, expectedCookieDeprecationHeader: true, expectedBody: `{"status":"ok","bidder_status":[` + - `{"bidder":"a","no_cookie":true,"usersync":{"url":"aURL","type":"redirect","supportCORS":true}}` + + `{"bidder":"a","no_cookie":true,"usersync":{"url":"aURL","type":"redirect"}}` + `]}` + "\n", setMetricsExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordCookieSync", metrics.CookieSyncOK).Once() @@ -327,7 +327,7 @@ func TestCookieSyncHandle(t *testing.T) { { BidderCode: "a", NoCookie: true, - UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "redirect", SupportCORS: true}, + UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "redirect"}, }, }, } @@ -588,6 +588,7 @@ func TestCookieSyncParseRequest(t *testing.T) { testCases := []struct { description string givenConfig config.UserSync + givenCookieSyncConfig config.CookieSync givenBody io.Reader givenGDPRConfig config.GDPR givenCCPAEnabled bool @@ -1108,6 +1109,78 @@ func TestCookieSyncParseRequest(t *testing.T) { expectedError: errCookieSyncAccountBlocked.Error(), givenAccountRequired: true, }, + { + description: "IFrame Disabled For All Bidders Via Account Config Wildcard", + givenBody: strings.NewReader(`{` + + `"bidders":["a", "b"],` + + `"account":"IFrameDisabledAllAccount"` + + `}`), + givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, + givenCCPAEnabled: true, + givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"a", "b", "c"}}, + Cooperative: config.UserSyncCooperative{ + EnabledByDefault: false, + }, + }, + expectedPrivacy: macros.UserSyncPrivacy{}, + expectedRequest: usersync.Request{ + Bidders: []string{"a", "b"}, + Cooperative: usersync.Cooperative{ + Enabled: true, + PriorityGroups: nil, + }, + Limit: 20, + Privacy: usersyncPrivacy{ + gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, + gdprSignal: -1, + }, + SyncTypeFilter: usersync.SyncTypeFilter{ + IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeExclude), + Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + }, + }, + }, + { + description: "IFrame Disabled For Specific Bidders", + givenBody: strings.NewReader(`{` + + `"bidders":["biddera", "bidderb"],` + + `"account":"IFrameDisabledAccount"` + + `}`), + givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, + givenCCPAEnabled: true, + givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"biddera", "bidderb", "bidderc"}}, + Cooperative: config.UserSyncCooperative{ + EnabledByDefault: false, + }, + }, + givenCookieSyncConfig: config.CookieSync{ + DisabledIFrameBidders: []string{"bidderb"}, + }, + expectedPrivacy: macros.UserSyncPrivacy{}, + expectedRequest: usersync.Request{ + Bidders: []string{"biddera", "bidderb"}, + Cooperative: usersync.Cooperative{ + Enabled: true, + PriorityGroups: nil, + }, + Limit: 20, + Privacy: usersyncPrivacy{ + gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, + gdprSignal: -1, + }, + SyncTypeFilter: usersync.SyncTypeFilter{ + IFrame: usersync.CompositeFilter{ + RequestFilter: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + AccountFilter: usersync.NewSpecificBidderFilter([]string{"bidderb", "biddera"}, usersync.BidderFilterModeExclude), + }, + Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + }, + }, + }, } for _, test := range testCases { @@ -1128,6 +1201,7 @@ func TestCookieSyncParseRequest(t *testing.T) { endpoint := cookieSyncEndpoint{ config: &config.Configuration{ UserSync: test.givenConfig, + CookieSync: test.givenCookieSyncConfig, AccountRequired: test.givenAccountRequired, }, privacyConfig: usersyncPrivacyConfig{ @@ -1139,6 +1213,8 @@ func TestCookieSyncParseRequest(t *testing.T) { accountsFetcher: FakeAccountsFetcher{AccountData: map[string]json.RawMessage{ "TestAccount": testAccountData, "DisabledAccount": json.RawMessage(`{"disabled":true}`), + "IFrameDisabledAccount": json.RawMessage(`{"cookie_sync": {"default_limit": 20, "max_limit": 30, "default_coop_sync": true, "disabled_iframe_bidders": ["biddera"]}}`), + "IFrameDisabledAllAccount": json.RawMessage(`{"cookie_sync": {"default_limit": 20, "max_limit": 30, "default_coop_sync": true, "disabled_iframe_bidders": ["*"]}}`), "ValidAccountInvalidActivities": json.RawMessage(`{"privacy":{"allowactivities":{"syncUser":{"rules":[{"condition":{"componentName": ["bidderA.bidderB.bidderC"]}}]}}}}`), }}, } @@ -1306,7 +1382,7 @@ func TestSetLimit(t *testing.T) { Limit: nil, }, givenAccount: &config.Account{ - CookieSync: config.CookieSync{ + CookieSync: config.AccountCookieSync{ DefaultLimit: nil, MaxLimit: nil, }, @@ -1321,7 +1397,7 @@ func TestSetLimit(t *testing.T) { Limit: intNegative, }, givenAccount: &config.Account{ - CookieSync: config.CookieSync{ + CookieSync: config.AccountCookieSync{ DefaultLimit: int20, }, }, @@ -1335,7 +1411,7 @@ func TestSetLimit(t *testing.T) { Limit: int0, }, givenAccount: &config.Account{ - CookieSync: config.CookieSync{ + CookieSync: config.AccountCookieSync{ DefaultLimit: int20, }, }, @@ -1349,7 +1425,7 @@ func TestSetLimit(t *testing.T) { Limit: int10, }, givenAccount: &config.Account{ - CookieSync: config.CookieSync{ + CookieSync: config.AccountCookieSync{ DefaultLimit: int20, MaxLimit: int30, }, @@ -1364,7 +1440,7 @@ func TestSetLimit(t *testing.T) { Limit: int30, }, givenAccount: &config.Account{ - CookieSync: config.CookieSync{ + CookieSync: config.AccountCookieSync{ DefaultLimit: int20, MaxLimit: int10, }, @@ -1379,7 +1455,7 @@ func TestSetLimit(t *testing.T) { Limit: intMax, }, givenAccount: &config.Account{ - CookieSync: config.CookieSync{}, + CookieSync: config.AccountCookieSync{}, }, expectedRequest: cookieSyncRequest{ Limit: intMax, @@ -1412,7 +1488,7 @@ func TestSetCooperativeSync(t *testing.T) { CooperativeSync: nil, }, givenAccount: &config.Account{ - CookieSync: config.CookieSync{ + CookieSync: config.AccountCookieSync{ DefaultCoopSync: nil, }, }, @@ -1426,7 +1502,7 @@ func TestSetCooperativeSync(t *testing.T) { CooperativeSync: nil, }, givenAccount: &config.Account{ - CookieSync: config.CookieSync{ + CookieSync: config.AccountCookieSync{ DefaultCoopSync: &coopSyncTrue, }, }, @@ -1440,7 +1516,7 @@ func TestSetCooperativeSync(t *testing.T) { CooperativeSync: &coopSyncTrue, }, givenAccount: &config.Account{ - CookieSync: config.CookieSync{ + CookieSync: config.AccountCookieSync{ DefaultCoopSync: nil, }, }, @@ -1454,7 +1530,7 @@ func TestSetCooperativeSync(t *testing.T) { CooperativeSync: &coopSyncFalse, }, givenAccount: &config.Account{ - CookieSync: config.CookieSync{ + CookieSync: config.AccountCookieSync{ DefaultCoopSync: &coopSyncTrue, }, }, @@ -1537,6 +1613,188 @@ func TestCookieSyncWriteParseRequestErrorMetrics(t *testing.T) { } } +func TestMergeDisabledIFrameBidders(t *testing.T) { + testCases := map[string]struct { + givenHost []string + givenAccount []string + expected []string + }{ + "both_nil": { + givenHost: nil, + givenAccount: nil, + expected: nil, + }, + "host_only": { + givenHost: []string{"bidderA", "bidderB"}, + givenAccount: nil, + expected: []string{"bidderA", "bidderB"}, + }, + "account_only": { + givenHost: nil, + givenAccount: []string{"bidderA", "bidderB"}, + expected: []string{"bidderA", "bidderB"}, + }, + "union": { + givenHost: []string{"bidderA"}, + givenAccount: []string{"bidderB"}, + expected: []string{"bidderA", "bidderB"}, + }, + "dedupe_host_precedence": { + givenHost: []string{"bidderA", "bidderB"}, + givenAccount: []string{"bidderB", "bidderC"}, + expected: []string{"bidderA", "bidderB", "bidderC"}, + }, + "wildcard_from_host": { + givenHost: []string{"*"}, + givenAccount: []string{"bidderA"}, + expected: []string{"*", "bidderA"}, + }, + "wildcard_from_account": { + givenHost: []string{"bidderA"}, + givenAccount: []string{"*"}, + expected: []string{"bidderA", "*"}, + }, + "wildcard_not_first_in_host": { + givenHost: []string{"bidderA", "*", "bidderB"}, + givenAccount: []string{"bidderC"}, + expected: []string{"bidderA", "*", "bidderB", "bidderC"}, + }, + "wildcard_not_first_in_account": { + givenHost: []string{"bidderA"}, + givenAccount: []string{"bidderB", "*"}, + expected: []string{"bidderA", "bidderB", "*"}, + }, + "wildcard_in_both_deduped": { + givenHost: []string{"bidderA", "*"}, + givenAccount: []string{"*", "bidderB"}, + expected: []string{"bidderA", "*", "bidderB"}, + }, + } + + for name, test := range testCases { + t.Run(name, func(t *testing.T) { + result := mergeDisabledIFrameBidders(test.givenHost, test.givenAccount) + assert.Equal(t, test.expected, result) + }) + } +} + +func TestApplyDisabledIFrameBidders(t *testing.T) { + allowAll := usersync.SyncTypeFilter{ + IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + } + + testCases := map[string]struct { + givenFilter usersync.SyncTypeFilter + givenBidders []string + expectedIFrame map[string]bool + expectedRedirect map[string]bool + expectedExactSync *usersync.SyncTypeFilter + }{ + "nil": { + givenFilter: allowAll, + givenBidders: nil, + expectedExactSync: &usersync.SyncTypeFilter{ + IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + }, + }, + "empty": { + givenFilter: allowAll, + givenBidders: []string{}, + expectedExactSync: &usersync.SyncTypeFilter{ + IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + }, + }, + "wildcard": { + givenFilter: allowAll, + givenBidders: []string{"*"}, + expectedExactSync: &usersync.SyncTypeFilter{ + IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeExclude), + Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + }, + }, + "specific_bidders": { + givenFilter: allowAll, + givenBidders: []string{"bidderA", "bidderB"}, + expectedIFrame: map[string]bool{ + "biddera": false, + "bidderb": false, + "bidderc": true, + }, + expectedRedirect: map[string]bool{ + "biddera": true, + }, + }, + // wildcard in givenBidders overrides the request-level redirect filter + "wildcard_overrides_request_filter": { + givenFilter: usersync.SyncTypeFilter{ + IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + Redirect: usersync.NewSpecificBidderFilter([]string{"biddera"}, usersync.BidderFilterModeExclude), + }, + givenBidders: []string{"*"}, + expectedExactSync: &usersync.SyncTypeFilter{ + IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeExclude), + Redirect: usersync.NewSpecificBidderFilter([]string{"biddera"}, usersync.BidderFilterModeExclude), + }, + }, + // request already excludes all iframe; account restriction still results in all blocked + "request_excludes_all": { + givenFilter: usersync.SyncTypeFilter{ + IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeExclude), + Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + }, + givenBidders: []string{"bidderA"}, + expectedIFrame: map[string]bool{ + "biddera": false, + "bidderb": false, + }, + }, + // request includes specific bidders; account disables one of them + "request_includes_specific": { + givenFilter: usersync.SyncTypeFilter{ + IFrame: usersync.NewSpecificBidderFilter([]string{"bidderA", "bidderB"}, usersync.BidderFilterModeInclude), + Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + }, + givenBidders: []string{"bidderA"}, + expectedIFrame: map[string]bool{ + "biddera": false, + "bidderb": true, + "bidderc": false, + }, + }, + // wildcard takes precedence when mixed with specific bidders + "wildcard_with_specific": { + givenFilter: allowAll, + givenBidders: []string{"*", "biddera"}, + expectedExactSync: &usersync.SyncTypeFilter{ + IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeExclude), + Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + }, + }, + } + + for name, test := range testCases { + t.Run(name, func(t *testing.T) { + result := applyDisabledIFrameBidders(test.givenFilter, test.givenBidders) + + if test.expectedExactSync != nil { + assert.Equal(t, *test.expectedExactSync, result) + } + + for bidder, expected := range test.expectedIFrame { + assert.Equal(t, expected, result.IFrame.Allowed(bidder), "IFrame.Allowed(%s)", bidder) + } + + for bidder, expected := range test.expectedRedirect { + assert.Equal(t, expected, result.Redirect.Allowed(bidder), "Redirect.Allowed(%s)", bidder) + } + }) + } +} + func TestParseTypeFilter(t *testing.T) { testCases := []struct { description string @@ -1793,12 +2051,12 @@ func TestCookieSyncHandleResponse(t *testing.T) { privacyMacros := macros.UserSyncPrivacy{USPrivacy: "anyConsent"} // The & in the URL is necessary to test proper JSON encoding. - syncA := usersync.Sync{URL: "https://syncA.com/sync?a=1&b=2", Type: usersync.SyncTypeRedirect, SupportCORS: true} + syncA := usersync.Sync{URL: "https://syncA.com/sync?a=1&b=2", Type: usersync.SyncTypeRedirect} syncerA := MockSyncer{} syncerA.On("GetSync", syncTypeExpected, privacyMacros).Return(syncA, nil).Maybe() // The & in the URL is necessary to test proper JSON encoding. - syncB := usersync.Sync{URL: "https://syncB.com/sync?a=1&b=2", Type: usersync.SyncTypeRedirect, SupportCORS: false} + syncB := usersync.Sync{URL: "https://syncB.com/sync?a=1&b=2", Type: usersync.SyncTypeRedirect} syncerB := MockSyncer{} syncerB.On("GetSync", syncTypeExpected, privacyMacros).Return(syncB, nil).Maybe() @@ -1837,7 +2095,7 @@ func TestCookieSyncHandleResponse(t *testing.T) { givenCookieHasSyncs: true, givenSyncersChosen: []usersync.SyncerChoice{{Bidder: "foo", Syncer: &syncerA}}, expectedJSON: `{"status":"ok","bidder_status":[` + - `{"bidder":"foo","no_cookie":true,"usersync":{"url":"https://syncA.com/sync?a=1&b=2","type":"redirect","supportCORS":true}}` + + `{"bidder":"foo","no_cookie":true,"usersync":{"url":"https://syncA.com/sync?a=1&b=2","type":"redirect"}}` + `]}` + "\n", expectedAnalytics: analytics.CookieSyncObject{ Status: 200, @@ -1845,7 +2103,7 @@ func TestCookieSyncHandleResponse(t *testing.T) { { BidderCode: "foo", NoCookie: true, - UsersyncInfo: &analytics.UsersyncInfo{URL: "https://syncA.com/sync?a=1&b=2", Type: "redirect", SupportCORS: true}, + UsersyncInfo: &analytics.UsersyncInfo{URL: "https://syncA.com/sync?a=1&b=2", Type: "redirect"}, }, }, }, @@ -1855,7 +2113,7 @@ func TestCookieSyncHandleResponse(t *testing.T) { givenCookieHasSyncs: true, givenSyncersChosen: []usersync.SyncerChoice{{Bidder: "foo", Syncer: &syncerA}, {Bidder: "bar", Syncer: &syncerB}}, expectedJSON: `{"status":"ok","bidder_status":[` + - `{"bidder":"foo","no_cookie":true,"usersync":{"url":"https://syncA.com/sync?a=1&b=2","type":"redirect","supportCORS":true}},` + + `{"bidder":"foo","no_cookie":true,"usersync":{"url":"https://syncA.com/sync?a=1&b=2","type":"redirect"}},` + `{"bidder":"bar","no_cookie":true,"usersync":{"url":"https://syncB.com/sync?a=1&b=2","type":"redirect"}}` + `]}` + "\n", expectedAnalytics: analytics.CookieSyncObject{ @@ -1864,12 +2122,12 @@ func TestCookieSyncHandleResponse(t *testing.T) { { BidderCode: "foo", NoCookie: true, - UsersyncInfo: &analytics.UsersyncInfo{URL: "https://syncA.com/sync?a=1&b=2", Type: "redirect", SupportCORS: true}, + UsersyncInfo: &analytics.UsersyncInfo{URL: "https://syncA.com/sync?a=1&b=2", Type: "redirect"}, }, { BidderCode: "bar", NoCookie: true, - UsersyncInfo: &analytics.UsersyncInfo{URL: "https://syncB.com/sync?a=1&b=2", Type: "redirect", SupportCORS: false}, + UsersyncInfo: &analytics.UsersyncInfo{URL: "https://syncB.com/sync?a=1&b=2", Type: "redirect"}, }, }, }, @@ -1887,7 +2145,7 @@ func TestCookieSyncHandleResponse(t *testing.T) { { BidderCode: "bar", NoCookie: true, - UsersyncInfo: &analytics.UsersyncInfo{URL: "https://syncB.com/sync?a=1&b=2", Type: "redirect", SupportCORS: false}, + UsersyncInfo: &analytics.UsersyncInfo{URL: "https://syncB.com/sync?a=1&b=2", Type: "redirect"}, }, }, }, @@ -1956,14 +2214,14 @@ func TestMapBidderStatusToAnalytics(t *testing.T) { { BidderCode: "a", NoCookie: true, - UsersyncInfo: cookieSyncResponseSync{URL: "aURL", Type: "aType", SupportCORS: false}, + UsersyncInfo: cookieSyncResponseSync{URL: "aURL", Type: "aType"}, }, }, expected: []*analytics.CookieSyncBidder{ { BidderCode: "a", NoCookie: true, - UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "aType", SupportCORS: false}, + UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "aType"}, }, }, }, @@ -1973,24 +2231,24 @@ func TestMapBidderStatusToAnalytics(t *testing.T) { { BidderCode: "a", NoCookie: true, - UsersyncInfo: cookieSyncResponseSync{URL: "aURL", Type: "aType", SupportCORS: false}, + UsersyncInfo: cookieSyncResponseSync{URL: "aURL", Type: "aType"}, }, { BidderCode: "b", NoCookie: false, - UsersyncInfo: cookieSyncResponseSync{URL: "bURL", Type: "bType", SupportCORS: true}, + UsersyncInfo: cookieSyncResponseSync{URL: "bURL", Type: "bType"}, }, }, expected: []*analytics.CookieSyncBidder{ { BidderCode: "a", NoCookie: true, - UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "aType", SupportCORS: false}, + UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "aType"}, }, { BidderCode: "b", NoCookie: false, - UsersyncInfo: &analytics.UsersyncInfo{URL: "bURL", Type: "bType", SupportCORS: true}, + UsersyncInfo: &analytics.UsersyncInfo{URL: "bURL", Type: "bType"}, }, }, }, @@ -2517,7 +2775,7 @@ func TestCookieSyncFindPriorityGroups(t *testing.T) { testCases := []struct { description string givenGlobalConfig config.UserSync - givenAccountCookieSync config.CookieSync + givenAccountCookieSync config.AccountCookieSync expectedPriorityGroups [][]string }{ { @@ -2525,7 +2783,7 @@ func TestCookieSyncFindPriorityGroups(t *testing.T) { givenGlobalConfig: config.UserSync{ PriorityGroups: [][]string{{"global1", "global2"}, {"global3"}}, }, - givenAccountCookieSync: config.CookieSync{ + givenAccountCookieSync: config.AccountCookieSync{ DefaultCoopSync: ptrutil.ToPtr(true), PriorityGroups: [][]string{{"account1", "account2"}, {"account3"}}, }, @@ -2536,7 +2794,7 @@ func TestCookieSyncFindPriorityGroups(t *testing.T) { givenGlobalConfig: config.UserSync{ PriorityGroups: [][]string{{"global1", "global2"}, {"global3"}}, }, - givenAccountCookieSync: config.CookieSync{ + givenAccountCookieSync: config.AccountCookieSync{ DefaultCoopSync: ptrutil.ToPtr(false), PriorityGroups: [][]string{{"account1", "account2"}, {"account3"}}, }, @@ -2547,7 +2805,7 @@ func TestCookieSyncFindPriorityGroups(t *testing.T) { givenGlobalConfig: config.UserSync{ PriorityGroups: [][]string{{"global1", "global2"}, {"global3"}}, }, - givenAccountCookieSync: config.CookieSync{ + givenAccountCookieSync: config.AccountCookieSync{ DefaultCoopSync: nil, PriorityGroups: [][]string{{"account1", "account2"}, {"account3"}}, }, @@ -2558,7 +2816,7 @@ func TestCookieSyncFindPriorityGroups(t *testing.T) { givenGlobalConfig: config.UserSync{ PriorityGroups: [][]string{{"global1", "global2"}, {"global3"}}, }, - givenAccountCookieSync: config.CookieSync{ + givenAccountCookieSync: config.AccountCookieSync{ DefaultCoopSync: ptrutil.ToPtr(true), PriorityGroups: [][]string{}, }, @@ -2569,7 +2827,7 @@ func TestCookieSyncFindPriorityGroups(t *testing.T) { givenGlobalConfig: config.UserSync{ PriorityGroups: [][]string{{"global1", "global2"}, {"global3"}}, }, - givenAccountCookieSync: config.CookieSync{ + givenAccountCookieSync: config.AccountCookieSync{ DefaultCoopSync: ptrutil.ToPtr(true), PriorityGroups: nil, }, @@ -2580,7 +2838,7 @@ func TestCookieSyncFindPriorityGroups(t *testing.T) { givenGlobalConfig: config.UserSync{ PriorityGroups: nil, }, - givenAccountCookieSync: config.CookieSync{ + givenAccountCookieSync: config.AccountCookieSync{ DefaultCoopSync: nil, PriorityGroups: [][]string{{"account1", "account2"}}, }, @@ -2603,7 +2861,7 @@ func TestCookieSyncFindPriorityGroups(t *testing.T) { } // createAccountJSON creates a JSON representation of account config for testing -func createAccountJSON(priorityGroups [][]string, defaultCoopSync *bool) json.RawMessage { +func createAccountJSON(priorityGroups [][]string, defaultCoopSync *bool, priorityGroupsOnly *bool) json.RawMessage { account := map[string]interface{}{ "cookie_sync": map[string]interface{}{ "priority_groups": priorityGroups, @@ -2614,6 +2872,10 @@ func createAccountJSON(priorityGroups [][]string, defaultCoopSync *bool) json.Ra account["cookie_sync"].(map[string]interface{})["default_coop_sync"] = *defaultCoopSync } + if priorityGroupsOnly != nil { + account["cookie_sync"].(map[string]interface{})["priority_groups_only"] = *priorityGroupsOnly + } + jsonData, _ := json.Marshal(account) return json.RawMessage(jsonData) } @@ -2621,15 +2883,15 @@ func createAccountJSON(priorityGroups [][]string, defaultCoopSync *bool) json.Ra func TestCookieSyncPriorityGroupsIntegration(t *testing.T) { // Setup test syncers syncerA := MockSyncer{} - syncerA.On("GetSync", mock.Anything, mock.Anything).Return(usersync.Sync{URL: "https://sync.bidderA.com", Type: usersync.SyncTypeRedirect, SupportCORS: false}, nil).Maybe() + syncerA.On("GetSync", mock.Anything, mock.Anything).Return(usersync.Sync{URL: "https://sync.bidderA.com", Type: usersync.SyncTypeRedirect}, nil).Maybe() syncerA.On("Key").Return("appnexus").Maybe() syncerA.On("SupportsType", mock.Anything).Return(true).Maybe() syncerB := MockSyncer{} - syncerB.On("GetSync", mock.Anything, mock.Anything).Return(usersync.Sync{URL: "https://sync.bidderB.com", Type: usersync.SyncTypeRedirect, SupportCORS: false}, nil).Maybe() + syncerB.On("GetSync", mock.Anything, mock.Anything).Return(usersync.Sync{URL: "https://sync.bidderB.com", Type: usersync.SyncTypeRedirect}, nil).Maybe() syncerB.On("Key").Return("rubicon").Maybe() syncerB.On("SupportsType", mock.Anything).Return(true).Maybe() syncerC := MockSyncer{} - syncerC.On("GetSync", mock.Anything, mock.Anything).Return(usersync.Sync{URL: "https://sync.bidderC.com", Type: usersync.SyncTypeRedirect, SupportCORS: false}, nil).Maybe() + syncerC.On("GetSync", mock.Anything, mock.Anything).Return(usersync.Sync{URL: "https://sync.bidderC.com", Type: usersync.SyncTypeRedirect}, nil).Maybe() syncerC.On("Key").Return("pubmatic").Maybe() syncerC.On("SupportsType", mock.Anything).Return(true).Maybe() // Need to choose real bidder names because the standard chooser is hardcoded to validate against them @@ -2652,13 +2914,15 @@ func TestCookieSyncPriorityGroupsIntegration(t *testing.T) { } testCases := []struct { - description string - givenRequestBody string - givenAccountPriorityGroups [][]string - givenAccountDefaultCoopSync *bool - givenGlobalPriorityGroups [][]string - givenCooperativeEnabledByDef bool - shouldContainBidders []string + description string + givenRequestBody string + givenAccountPriorityGroups [][]string + givenAccountDefaultCoopSync *bool + givenAccountPriorityGroupsOnly *bool + givenGlobalPriorityGroups [][]string + givenCooperativeEnabledByDef bool + shouldContainBidders []string + shouldNotContainBidders []string }{ { description: "Account-level priority groups used with cooperative sync enabled", @@ -2713,6 +2977,31 @@ func TestCookieSyncPriorityGroupsIntegration(t *testing.T) { givenCooperativeEnabledByDef: false, shouldContainBidders: []string{"appnexus", "rubicon", "pubmatic"}, }, + { + description: "Priority groups only — remaining bidders excluded", + givenRequestBody: `{"bidders":["appnexus"], "coopSync": true, "limit": 10, "account": "test_account"}`, + givenAccountPriorityGroups: [][]string{ + {"rubicon"}, + }, + givenAccountDefaultCoopSync: ptrutil.ToPtr(true), + givenAccountPriorityGroupsOnly: ptrutil.ToPtr(true), + givenGlobalPriorityGroups: [][]string{{"ignored"}}, + givenCooperativeEnabledByDef: false, + shouldContainBidders: []string{"appnexus", "rubicon"}, + shouldNotContainBidders: []string{"pubmatic"}, + }, + { + description: "Priority groups only false — remaining bidders included", + givenRequestBody: `{"bidders":["appnexus"], "coopSync": true, "limit": 10, "account": "test_account"}`, + givenAccountPriorityGroups: [][]string{ + {"rubicon"}, + }, + givenAccountDefaultCoopSync: ptrutil.ToPtr(true), + givenAccountPriorityGroupsOnly: ptrutil.ToPtr(false), + givenGlobalPriorityGroups: [][]string{{"ignored"}}, + givenCooperativeEnabledByDef: false, + shouldContainBidders: []string{"appnexus", "rubicon", "pubmatic"}, + }, } for _, tc := range testCases { @@ -2750,7 +3039,7 @@ func TestCookieSyncPriorityGroupsIntegration(t *testing.T) { &mockAnalytics, &FakeAccountsFetcher{ AccountData: map[string]json.RawMessage{ - "test_account": createAccountJSON(tc.givenAccountPriorityGroups, tc.givenAccountDefaultCoopSync), + "test_account": createAccountJSON(tc.givenAccountPriorityGroups, tc.givenAccountDefaultCoopSync, tc.givenAccountPriorityGroupsOnly), }, }, bidders, @@ -2780,6 +3069,11 @@ func TestCookieSyncPriorityGroupsIntegration(t *testing.T) { for _, expected := range tc.shouldContainBidders { assert.Contains(t, actualBidders, expected, "Expected bidder %s to be present in response", expected) } + + // Check that excluded bidders are not present + for _, excluded := range tc.shouldNotContainBidders { + assert.NotContains(t, actualBidders, excluded, "Bidder %s should not be present in response", excluded) + } }) } } @@ -2788,7 +3082,7 @@ func TestCookieSyncPriorityGroupsEdgeCases(t *testing.T) { // Setup basic syncers syncerA := MockSyncer{} syncerA.On("Key").Return("bidderA") - syncerA.On("GetSync", mock.Anything, mock.Anything).Return(usersync.Sync{URL: "https://sync.bidderA.com", Type: usersync.SyncTypeRedirect, SupportCORS: false}, nil).Maybe() + syncerA.On("GetSync", mock.Anything, mock.Anything).Return(usersync.Sync{URL: "https://sync.bidderA.com", Type: usersync.SyncTypeRedirect}, nil).Maybe() syncerA.On("SupportsType", mock.Anything).Return(true).Maybe() syncersByBidder := map[string]usersync.Syncer{ @@ -2923,7 +3217,7 @@ func TestCookieSyncPriorityGroupsEdgeCases(t *testing.T) { &mockAnalytics, &FakeAccountsFetcher{ AccountData: map[string]json.RawMessage{ - "test_account": createAccountJSON(tc.givenAccountPriorityGroups, tc.givenAccountDefaultCoopSync), + "test_account": createAccountJSON(tc.givenAccountPriorityGroups, tc.givenAccountDefaultCoopSync, nil), }, }, bidders, diff --git a/endpoints/currency_rates.go b/endpoints/currency_rates.go index f7d20cd79b..c6cacc6738 100644 --- a/endpoints/currency_rates.go +++ b/endpoints/currency_rates.go @@ -4,9 +4,9 @@ import ( "net/http" "time" - "github.com/prebid/prebid-server/v3/currency" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // currencyRatesInfo holds currency rates information. diff --git a/endpoints/currency_rates_test.go b/endpoints/currency_rates_test.go index 00da093a2d..21d314a9f9 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/v3/currency" + "github.com/prebid/prebid-server/v4/currency" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/events/account_test.go b/endpoints/events/account_test.go index b379621b06..cbd0a5c818 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/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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/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 fa2fca2f96..c1a253b3d3 100644 --- a/endpoints/events/event.go +++ b/endpoints/events/event.go @@ -10,17 +10,17 @@ import ( "time" "unicode" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/julienschmidt/httprouter" - 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" + accountService "github.com/prebid/prebid-server/v4/account" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/util/httputil" ) const ( diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go index eb52d8c128..8a32da7b25 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/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/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/stored_requests" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/events/vtrack.go b/endpoints/events/vtrack.go index ff846f694f..9a2e6ce5f3 100644 --- a/endpoints/events/vtrack.go +++ b/endpoints/events/vtrack.go @@ -10,16 +10,16 @@ import ( "time" "github.com/julienschmidt/httprouter" - 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/logger" - "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" + accountService "github.com/prebid/prebid-server/v4/account" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/prebid_cache_client" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/endpoints/events/vtrack_test.go b/endpoints/events/vtrack_test.go index 1345d563db..0648bdbbb4 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/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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/prebid_cache_client" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/getuids.go b/endpoints/getuids.go index dac114da22..ecc176b07a 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/v3/config" - "github.com/prebid/prebid-server/v3/usersync" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/usersync" "encoding/json" ) diff --git a/endpoints/getuids_test.go b/endpoints/getuids_test.go index 1092c51f79..6b0ff5a7cc 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/v3/config" + "github.com/prebid/prebid-server/v4/config" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/info/bidders.go b/endpoints/info/bidders.go index d5f6ea330f..67b9887314 100644 --- a/endpoints/info/bidders.go +++ b/endpoints/info/bidders.go @@ -6,9 +6,9 @@ import ( "strings" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) var invalidEnabledOnlyMsg = []byte(`Invalid value for 'enabledonly' query param, must be of boolean type`) diff --git a/endpoints/info/bidders_detail.go b/endpoints/info/bidders_detail.go index 1a0936a07b..5bf97f3cea 100644 --- a/endpoints/info/bidders_detail.go +++ b/endpoints/info/bidders_detail.go @@ -7,10 +7,10 @@ import ( "strings" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/endpoints/info/bidders_detail_test.go b/endpoints/info/bidders_detail_test.go index d98e9ec094..2ee6df0f56 100644 --- a/endpoints/info/bidders_detail_test.go +++ b/endpoints/info/bidders_detail_test.go @@ -9,9 +9,9 @@ import ( "testing" "github.com/julienschmidt/httprouter" - "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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/info/bidders_test.go b/endpoints/info/bidders_test.go index 20b5ea0401..9a30c28756 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/v3/config" + "github.com/prebid/prebid-server/v4/config" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 48a80d9cab..cb494d2876 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -15,29 +15,29 @@ import ( "github.com/julienschmidt/httprouter" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/openrtb/v20/openrtb3" - "github.com/prebid/prebid-server/v3/hooks/hookexecution" - "github.com/prebid/prebid-server/v3/ortb" - "github.com/prebid/prebid-server/v3/util/uuidutil" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/util/uuidutil" jsonpatch "gopkg.in/evanphx/json-patch.v5" - 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/hooks" - "github.com/prebid/prebid-server/v3/logger" - "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" + accountService "github.com/prebid/prebid-server/v4/account" + "github.com/prebid/prebid-server/v4/amp" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/exchange" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v4/stored_responses" + "github.com/prebid/prebid-server/v4/usersync" + "github.com/prebid/prebid-server/v4/util/iputil" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/version" ) const defaultAmpRequestTimeoutMillis = 900 diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go index 126d86802b..cb31a2b6ed 100644 --- a/endpoints/openrtb2/amp_auction_test.go +++ b/endpoints/openrtb2/amp_auction_test.go @@ -19,23 +19,23 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/prebid/prebid-server/v3/adapters" - "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/amp" + "github.com/prebid/prebid-server/v4/analytics" + analyticsBuild "github.com/prebid/prebid-server/v4/analytics/build" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/exchange" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/metrics" + metricsConfig "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // TestGoodRequests makes sure that the auction runs properly-formatted stored bids correctly. @@ -2491,7 +2491,7 @@ func TestAmpAuctionDebugWarningsOnly(t *testing.T) { ) for _, test := range testCases { - httpReq := httptest.NewRequest("GET", fmt.Sprintf("/openrtb2/auction/amp"+test.requestURLArguments), nil) + httpReq := httptest.NewRequest("GET", "/openrtb2/auction/amp"+test.requestURLArguments, nil) test.addRequestHeaders(httpReq) recorder := httptest.NewRecorder() diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 4a75a70957..5df5cceba7 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -21,38 +21,38 @@ import ( "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/openrtb/v20/openrtb3" - "github.com/prebid/prebid-server/v3/bidadjustment" - "github.com/prebid/prebid-server/v3/hooks" - "github.com/prebid/prebid-server/v3/logger" - "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" + "github.com/prebid/prebid-server/v4/bidadjustment" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/privacysandbox" + "github.com/prebid/prebid-server/v4/schain" "golang.org/x/net/publicsuffix" jsonpatch "gopkg.in/evanphx/json-patch.v5" - 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" + accountService "github.com/prebid/prebid-server/v4/account" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/exchange" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/prebid_cache_client" + "github.com/prebid/prebid-server/v4/privacy/ccpa" + "github.com/prebid/prebid-server/v4/privacy/lmt" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v4/stored_responses" + "github.com/prebid/prebid-server/v4/usersync" + "github.com/prebid/prebid-server/v4/util/httputil" + "github.com/prebid/prebid-server/v4/util/iputil" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/uuidutil" + "github.com/prebid/prebid-server/v4/version" ) const ampChannel = "amp" diff --git a/endpoints/openrtb2/auction_benchmark_test.go b/endpoints/openrtb2/auction_benchmark_test.go index ab8cb4863a..7d963393b8 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/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" + analyticsBuild "github.com/prebid/prebid-server/v4/analytics/build" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/exchange" + "github.com/prebid/prebid-server/v4/experiment/adscert" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/macros" + metricsConfig "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v4/usersync" ) // benchmarkTestServer returns the header bidding test ad. This response was scraped from a real appnexus server response. diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 1bf947f453..b196f59066 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -23,25 +23,25 @@ import ( "github.com/julienschmidt/httprouter" gpplib "github.com/prebid/go-gpp" "github.com/prebid/openrtb/v20/openrtb2" - "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/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/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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/analytics" + analyticsBuild "github.com/prebid/prebid-server/v4/analytics/build" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/exchange" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/metrics" + metricsConfig "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v4/stored_responses" + "github.com/prebid/prebid-server/v4/util/iputil" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/openrtb2/interstitial.go b/endpoints/openrtb2/interstitial.go index 4cb9482c0d..7f39af0013 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/v3/config" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func processInterstitials(req *openrtb_ext.RequestWrapper) error { diff --git a/endpoints/openrtb2/interstitial_test.go b/endpoints/openrtb2/interstitial_test.go index d5276d18db..5f4e4e154f 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index e320a940e6..d0316db77c 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/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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/analytics" + analyticsBuild "github.com/prebid/prebid-server/v4/analytics/build" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/exchange" + "github.com/prebid/prebid-server/v4/experiment/adscert" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/metrics" + metricsConfig "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/ortb" + pbc "github.com/prebid/prebid-server/v4/prebid_cache_client" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v4/util/iputil" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/uuidutil" jsonpatch "gopkg.in/evanphx/json-patch.v5" ) diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 047511f379..04dffb1dda 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -16,29 +16,29 @@ import ( "github.com/gofrs/uuid" "github.com/julienschmidt/httprouter" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/hooks" - "github.com/prebid/prebid-server/v3/hooks/hookexecution" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/ortb" - "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/privacy" jsonpatch "gopkg.in/evanphx/json-patch.v5" - 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" + accountService "github.com/prebid/prebid-server/v4/account" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/exchange" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/prebid_cache_client" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v4/usersync" + "github.com/prebid/prebid-server/v4/util/iputil" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/uuidutil" + "github.com/prebid/prebid-server/v4/version" ) var defaultRequestTimeout int64 = 5000 @@ -122,6 +122,12 @@ func NewVideoEndpoint( func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { start := time.Now() + if !deps.cfg.Video.EnableDeprecatedEndpoint { + w.WriteHeader(http.StatusNotImplemented) + w.Write([]byte("The video endpoint is deprecated and will be removed in 5.0. You may re-enable it via the host configuration setting video.enable_deprecated_endpoint")) + return + } + vo := analytics.VideoObject{ Status: http.StatusOK, Errors: make([]error, 0), diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index cd3e0d9c37..1a4d4f9934 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/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/prebid-server/v4/analytics" + analyticsBuild "github.com/prebid/prebid-server/v4/analytics/build" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/exchange" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/metrics" + metricsConfig "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/prebid_cache_client" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" @@ -1273,7 +1273,7 @@ func mockDepsWithMetrics(t *testing.T, ex *mockExchangeVideo) (*endpointDeps, *m &mockVideoStoredReqFetcher{}, &mockVideoStoredReqFetcher{}, &mockAccountFetcher{data: mockVideoAccountData}, - &config.Configuration{MaxRequestSize: maxSize}, + &config.Configuration{Video: config.Video{EnableDeprecatedEndpoint: true}, MaxRequestSize: maxSize}, metrics, mockModule, map[string]string{}, @@ -1324,7 +1324,7 @@ func mockDeps(t *testing.T, ex *mockExchangeVideo) *endpointDeps { &mockVideoStoredReqFetcher{}, &mockVideoStoredReqFetcher{}, &mockAccountFetcher{data: mockVideoAccountData}, - &config.Configuration{MaxRequestSize: maxSize}, + &config.Configuration{Video: config.Video{EnableDeprecatedEndpoint: true}, MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, analyticsBuild.New(&config.Analytics{}), map[string]string{}, @@ -1349,7 +1349,7 @@ func mockDepsAppendBidderNames(t *testing.T, ex *mockExchangeAppendBidderNames) &mockVideoStoredReqFetcher{}, &mockVideoStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, - &config.Configuration{MaxRequestSize: maxSize}, + &config.Configuration{Video: config.Video{EnableDeprecatedEndpoint: true}, MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, analyticsBuild.New(&config.Analytics{}), map[string]string{}, @@ -1376,7 +1376,7 @@ func mockDepsNoBids(t *testing.T, ex *mockExchangeVideoNoBids) *endpointDeps { &mockVideoStoredReqFetcher{}, &mockVideoStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, - &config.Configuration{MaxRequestSize: maxSize}, + &config.Configuration{Video: config.Video{EnableDeprecatedEndpoint: true}, MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, analyticsBuild.New(&config.Analytics{}), map[string]string{}, @@ -1548,3 +1548,37 @@ func TestVideoRequestValidationFailed(t *testing.T) { assert.Equal(t, 500, recorder.Code, "Should catch error in request") assert.Equal(t, "Critical error while running the video endpoint: request.tmax must be nonnegative. Got -2", errorMessage, "Incorrect request validation message") } + +func TestVideoEndpointDisabled(t *testing.T) { + ex := &mockExchangeVideo{} + req := httptest.NewRequest("POST", "/openrtb2/video", strings.NewReader("{}")) + recorder := httptest.NewRecorder() + + deps := &endpointDeps{ + fakeUUIDGenerator{}, + ex, + ortb.NewRequestValidator(openrtb_ext.BuildBidderMap(), map[string]string{}, mockBidderParamValidator{}), + &mockVideoStoredReqFetcher{}, + &mockVideoStoredReqFetcher{}, + &mockAccountFetcher{data: mockVideoAccountData}, + &config.Configuration{Video: config.Video{EnableDeprecatedEndpoint: false}, MaxRequestSize: maxSize}, + &metricsConfig.NilMetricsEngine{}, + analyticsBuild.New(&config.Analytics{}), + map[string]string{}, + false, + []byte{}, + openrtb_ext.BuildBidderMap(), + ex.cache, + regexp.MustCompile(`[<>]`), + hardcodedResponseIPValidator{response: true}, + empty_fetcher.EmptyFetcher{}, + hooks.EmptyPlanBuilder{}, + nil, + openrtb_ext.NormalizeBidderName, + } + + deps.VideoAuctionEndpoint(recorder, req, nil) + + assert.Equal(t, http.StatusNotImplemented, recorder.Code, "Expected 501 status code when video endpoint is disabled") + assert.Equal(t, "The video endpoint is deprecated and will be removed in 5.0. You may re-enable it via the host configuration setting video.enable_deprecated_endpoint", recorder.Body.String(), "Unexpected error message") +} diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 8358761003..dcefe4f645 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/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" + accountService "github.com/prebid/prebid-server/v4/account" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/privacy" + gppPrivacy "github.com/prebid/prebid-server/v4/privacy/gpp" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/usersync" + "github.com/prebid/prebid-server/v4/util/httputil" + stringutil "github.com/prebid/prebid-server/v4/util/stringutil" ) const ( diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 78944da7c4..015566e5c0 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -12,18 +12,18 @@ import ( "testing" "time" - "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/prebid/prebid-server/v4/analytics" + analyticsBuild "github.com/prebid/prebid-server/v4/analytics/build" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/usersync" "github.com/stretchr/testify/assert" - metricsConf "github.com/prebid/prebid-server/v3/metrics/config" + metricsConf "github.com/prebid/prebid-server/v4/metrics/config" ) func TestSetUIDEndpoint(t *testing.T) { diff --git a/endpoints/version.go b/endpoints/version.go index b947c771fb..8a1f15599f 100644 --- a/endpoints/version.go +++ b/endpoints/version.go @@ -4,8 +4,8 @@ import ( "encoding/json" "net/http" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const versionEndpointValueNotSet = "not-set" diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index e6bba140a5..c8da847f76 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -1,270 +1,278 @@ package exchange import ( - "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/adagio" - "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/ads_interactive" - "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/aduptech" - "github.com/prebid/prebid-server/v3/adapters/advangelists" - "github.com/prebid/prebid-server/v3/adapters/adverxo" - "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/afront" - "github.com/prebid/prebid-server/v3/adapters/aidem" - "github.com/prebid/prebid-server/v3/adapters/aja" - "github.com/prebid/prebid-server/v3/adapters/akcelo" - "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/bidtheatre" - "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/blis" - "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/boldwin_rapid" - "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/clydo" - "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/connatix" - "github.com/prebid/prebid-server/v3/adapters/connectad" - "github.com/prebid/prebid-server/v3/adapters/consumable" - "github.com/prebid/prebid-server/v3/adapters/contxtful" - "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/exco" - "github.com/prebid/prebid-server/v3/adapters/feedad" - "github.com/prebid/prebid-server/v3/adapters/flatads" - "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/fwssp" - "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/goldbach" - "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/insticator" - "github.com/prebid/prebid-server/v3/adapters/interactiveoffers" - "github.com/prebid/prebid-server/v3/adapters/intertech" - "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/kobler" - "github.com/prebid/prebid-server/v3/adapters/krushmedia" - "github.com/prebid/prebid-server/v3/adapters/kueezrtb" - "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/loopme" - "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/madsense" - "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/mediasquare" - "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/mobkoi" - "github.com/prebid/prebid-server/v3/adapters/motorik" - "github.com/prebid/prebid-server/v3/adapters/msft" - "github.com/prebid/prebid-server/v3/adapters/nativery" - "github.com/prebid/prebid-server/v3/adapters/nativo" - "github.com/prebid/prebid-server/v3/adapters/nextmillennium" - "github.com/prebid/prebid-server/v3/adapters/nexx360" - "github.com/prebid/prebid-server/v3/adapters/nobid" - "github.com/prebid/prebid-server/v3/adapters/ogury" - "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/optidigital" - "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/rediads" - "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/seedtag" - "github.com/prebid/prebid-server/v3/adapters/sharethrough" - "github.com/prebid/prebid-server/v3/adapters/showheroes" - "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/smoot" - "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/sparteo" - "github.com/prebid/prebid-server/v3/adapters/sspBC" - "github.com/prebid/prebid-server/v3/adapters/startio" - "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/teqblaze" - "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/tradplus" - "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/zentotem" - "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" + "github.com/prebid/prebid-server/v4/adapters" + ttx "github.com/prebid/prebid-server/v4/adapters/33across" + "github.com/prebid/prebid-server/v4/adapters/aax" + "github.com/prebid/prebid-server/v4/adapters/aceex" + "github.com/prebid/prebid-server/v4/adapters/acuityads" + "github.com/prebid/prebid-server/v4/adapters/adagio" + "github.com/prebid/prebid-server/v4/adapters/adelement" + "github.com/prebid/prebid-server/v4/adapters/adf" + "github.com/prebid/prebid-server/v4/adapters/adgeneration" + "github.com/prebid/prebid-server/v4/adapters/adhese" + "github.com/prebid/prebid-server/v4/adapters/adkernel" + "github.com/prebid/prebid-server/v4/adapters/adkernelAdn" + "github.com/prebid/prebid-server/v4/adapters/adman" + "github.com/prebid/prebid-server/v4/adapters/admatic" + "github.com/prebid/prebid-server/v4/adapters/admixer" + "github.com/prebid/prebid-server/v4/adapters/adnuntius" + "github.com/prebid/prebid-server/v4/adapters/adot" + "github.com/prebid/prebid-server/v4/adapters/adpone" + "github.com/prebid/prebid-server/v4/adapters/adprime" + "github.com/prebid/prebid-server/v4/adapters/adquery" + "github.com/prebid/prebid-server/v4/adapters/adrino" + "github.com/prebid/prebid-server/v4/adapters/adtarget" + "github.com/prebid/prebid-server/v4/adapters/adtelligent" + "github.com/prebid/prebid-server/v4/adapters/adtonos" + "github.com/prebid/prebid-server/v4/adapters/adtrgtme" + "github.com/prebid/prebid-server/v4/adapters/aduptech" + "github.com/prebid/prebid-server/v4/adapters/advangelists" + "github.com/prebid/prebid-server/v4/adapters/adverxo" + "github.com/prebid/prebid-server/v4/adapters/adview" + "github.com/prebid/prebid-server/v4/adapters/adxcg" + "github.com/prebid/prebid-server/v4/adapters/adyoulike" + "github.com/prebid/prebid-server/v4/adapters/afront" + "github.com/prebid/prebid-server/v4/adapters/aidem" + "github.com/prebid/prebid-server/v4/adapters/aja" + "github.com/prebid/prebid-server/v4/adapters/akcelo" + "github.com/prebid/prebid-server/v4/adapters/algorix" + "github.com/prebid/prebid-server/v4/adapters/alkimi" + alliance_gravity "github.com/prebid/prebid-server/v4/adapters/alliance_gravity" + "github.com/prebid/prebid-server/v4/adapters/amx" + "github.com/prebid/prebid-server/v4/adapters/apacdex" + "github.com/prebid/prebid-server/v4/adapters/appnexus" + "github.com/prebid/prebid-server/v4/adapters/appush" + "github.com/prebid/prebid-server/v4/adapters/aso" + "github.com/prebid/prebid-server/v4/adapters/audienceNetwork" + "github.com/prebid/prebid-server/v4/adapters/automatad" + "github.com/prebid/prebid-server/v4/adapters/avocet" + "github.com/prebid/prebid-server/v4/adapters/axis" + "github.com/prebid/prebid-server/v4/adapters/axonix" + "github.com/prebid/prebid-server/v4/adapters/beachfront" + "github.com/prebid/prebid-server/v4/adapters/beintoo" + "github.com/prebid/prebid-server/v4/adapters/bematterfull" + "github.com/prebid/prebid-server/v4/adapters/beop" + "github.com/prebid/prebid-server/v4/adapters/between" + "github.com/prebid/prebid-server/v4/adapters/beyondmedia" + "github.com/prebid/prebid-server/v4/adapters/bidmachine" + "github.com/prebid/prebid-server/v4/adapters/bidmatic" + "github.com/prebid/prebid-server/v4/adapters/bidmyadz" + "github.com/prebid/prebid-server/v4/adapters/bidscube" + "github.com/prebid/prebid-server/v4/adapters/bidstack" + "github.com/prebid/prebid-server/v4/adapters/bidtheatre" + "github.com/prebid/prebid-server/v4/adapters/bigoad" + "github.com/prebid/prebid-server/v4/adapters/blasto" + "github.com/prebid/prebid-server/v4/adapters/bliink" + "github.com/prebid/prebid-server/v4/adapters/blis" + "github.com/prebid/prebid-server/v4/adapters/blue" + "github.com/prebid/prebid-server/v4/adapters/bluesea" + "github.com/prebid/prebid-server/v4/adapters/bmtm" + "github.com/prebid/prebid-server/v4/adapters/boldwin" + "github.com/prebid/prebid-server/v4/adapters/boldwin_rapid" + "github.com/prebid/prebid-server/v4/adapters/brave" + "github.com/prebid/prebid-server/v4/adapters/bwx" + cadentaperturemx "github.com/prebid/prebid-server/v4/adapters/cadent_aperture_mx" + "github.com/prebid/prebid-server/v4/adapters/ccx" + "github.com/prebid/prebid-server/v4/adapters/clydo" + "github.com/prebid/prebid-server/v4/adapters/cointraffic" + "github.com/prebid/prebid-server/v4/adapters/coinzilla" + "github.com/prebid/prebid-server/v4/adapters/colossus" + "github.com/prebid/prebid-server/v4/adapters/compass" + "github.com/prebid/prebid-server/v4/adapters/concert" + "github.com/prebid/prebid-server/v4/adapters/connatix" + "github.com/prebid/prebid-server/v4/adapters/connectad" + "github.com/prebid/prebid-server/v4/adapters/consumable" + "github.com/prebid/prebid-server/v4/adapters/contxtful" + "github.com/prebid/prebid-server/v4/adapters/conversant" + "github.com/prebid/prebid-server/v4/adapters/copper6ssp" + "github.com/prebid/prebid-server/v4/adapters/cpmstar" + "github.com/prebid/prebid-server/v4/adapters/criteo" + "github.com/prebid/prebid-server/v4/adapters/cwire" + "github.com/prebid/prebid-server/v4/adapters/datablocks" + "github.com/prebid/prebid-server/v4/adapters/decenterads" + "github.com/prebid/prebid-server/v4/adapters/deepintent" + "github.com/prebid/prebid-server/v4/adapters/definemedia" + "github.com/prebid/prebid-server/v4/adapters/dianomi" + "github.com/prebid/prebid-server/v4/adapters/displayio" + "github.com/prebid/prebid-server/v4/adapters/dmx" + "github.com/prebid/prebid-server/v4/adapters/driftpixel" + evolution "github.com/prebid/prebid-server/v4/adapters/e_volution" + "github.com/prebid/prebid-server/v4/adapters/edge226" + "github.com/prebid/prebid-server/v4/adapters/elementaltv" + "github.com/prebid/prebid-server/v4/adapters/emtv" + "github.com/prebid/prebid-server/v4/adapters/eplanning" + "github.com/prebid/prebid-server/v4/adapters/epom" + "github.com/prebid/prebid-server/v4/adapters/escalax" + "github.com/prebid/prebid-server/v4/adapters/eskimi" + "github.com/prebid/prebid-server/v4/adapters/exco" + "github.com/prebid/prebid-server/v4/adapters/ezoic" + "github.com/prebid/prebid-server/v4/adapters/feedad" + "github.com/prebid/prebid-server/v4/adapters/flatads" + "github.com/prebid/prebid-server/v4/adapters/flipp" + "github.com/prebid/prebid-server/v4/adapters/freewheelssp" + "github.com/prebid/prebid-server/v4/adapters/frvradn" + "github.com/prebid/prebid-server/v4/adapters/fwssp" + "github.com/prebid/prebid-server/v4/adapters/gamma" + "github.com/prebid/prebid-server/v4/adapters/gamoshi" + "github.com/prebid/prebid-server/v4/adapters/globalsun" + "github.com/prebid/prebid-server/v4/adapters/goldbach" + "github.com/prebid/prebid-server/v4/adapters/grid" + "github.com/prebid/prebid-server/v4/adapters/gumgum" + "github.com/prebid/prebid-server/v4/adapters/huaweiads" + "github.com/prebid/prebid-server/v4/adapters/imds" + "github.com/prebid/prebid-server/v4/adapters/impactify" + "github.com/prebid/prebid-server/v4/adapters/improvedigital" + "github.com/prebid/prebid-server/v4/adapters/infytv" + "github.com/prebid/prebid-server/v4/adapters/inmobi" + "github.com/prebid/prebid-server/v4/adapters/insticator" + "github.com/prebid/prebid-server/v4/adapters/intenze" + "github.com/prebid/prebid-server/v4/adapters/interactiveoffers" + "github.com/prebid/prebid-server/v4/adapters/invibes" + "github.com/prebid/prebid-server/v4/adapters/iqx" + "github.com/prebid/prebid-server/v4/adapters/iqzone" + "github.com/prebid/prebid-server/v4/adapters/ix" + "github.com/prebid/prebid-server/v4/adapters/jixie" + "github.com/prebid/prebid-server/v4/adapters/kargo" + "github.com/prebid/prebid-server/v4/adapters/kayzen" + "github.com/prebid/prebid-server/v4/adapters/kidoz" + "github.com/prebid/prebid-server/v4/adapters/kiviads" + "github.com/prebid/prebid-server/v4/adapters/kobler" + "github.com/prebid/prebid-server/v4/adapters/krushmedia" + "github.com/prebid/prebid-server/v4/adapters/kueezrtb" + "github.com/prebid/prebid-server/v4/adapters/lemmadigital" + "github.com/prebid/prebid-server/v4/adapters/limelightDigital" + lmkiviads "github.com/prebid/prebid-server/v4/adapters/lm_kiviads" + "github.com/prebid/prebid-server/v4/adapters/lockerdome" + "github.com/prebid/prebid-server/v4/adapters/logan" + "github.com/prebid/prebid-server/v4/adapters/logicad" + "github.com/prebid/prebid-server/v4/adapters/loopme" + "github.com/prebid/prebid-server/v4/adapters/loyal" + "github.com/prebid/prebid-server/v4/adapters/lunamedia" + "github.com/prebid/prebid-server/v4/adapters/mabidder" + "github.com/prebid/prebid-server/v4/adapters/madsense" + "github.com/prebid/prebid-server/v4/adapters/madvertise" + "github.com/prebid/prebid-server/v4/adapters/marsmedia" + "github.com/prebid/prebid-server/v4/adapters/mediago" + "github.com/prebid/prebid-server/v4/adapters/medianet" + "github.com/prebid/prebid-server/v4/adapters/mediasquare" + "github.com/prebid/prebid-server/v4/adapters/melozen" + "github.com/prebid/prebid-server/v4/adapters/metax" + "github.com/prebid/prebid-server/v4/adapters/mgid" + "github.com/prebid/prebid-server/v4/adapters/mgidX" + "github.com/prebid/prebid-server/v4/adapters/minutemedia" + "github.com/prebid/prebid-server/v4/adapters/missena" + "github.com/prebid/prebid-server/v4/adapters/mobfoxpb" + "github.com/prebid/prebid-server/v4/adapters/mobilefuse" + "github.com/prebid/prebid-server/v4/adapters/mobkoi" + "github.com/prebid/prebid-server/v4/adapters/motorik" + "github.com/prebid/prebid-server/v4/adapters/msft" + "github.com/prebid/prebid-server/v4/adapters/nativery" + "github.com/prebid/prebid-server/v4/adapters/nativo" + "github.com/prebid/prebid-server/v4/adapters/nextmillennium" + "github.com/prebid/prebid-server/v4/adapters/nexx360" + "github.com/prebid/prebid-server/v4/adapters/nobid" + "github.com/prebid/prebid-server/v4/adapters/ogury" + "github.com/prebid/prebid-server/v4/adapters/oms" + "github.com/prebid/prebid-server/v4/adapters/onetag" + "github.com/prebid/prebid-server/v4/adapters/openweb" + "github.com/prebid/prebid-server/v4/adapters/openx" + "github.com/prebid/prebid-server/v4/adapters/operaads" + "github.com/prebid/prebid-server/v4/adapters/optidigital" + "github.com/prebid/prebid-server/v4/adapters/oraki" + "github.com/prebid/prebid-server/v4/adapters/orbidder" + "github.com/prebid/prebid-server/v4/adapters/outbrain" + "github.com/prebid/prebid-server/v4/adapters/ownadx" + "github.com/prebid/prebid-server/v4/adapters/pangle" + "github.com/prebid/prebid-server/v4/adapters/pgamssp" + "github.com/prebid/prebid-server/v4/adapters/pixfuture" + "github.com/prebid/prebid-server/v4/adapters/playdigo" + "github.com/prebid/prebid-server/v4/adapters/proxistore" + "github.com/prebid/prebid-server/v4/adapters/pubmatic" + "github.com/prebid/prebid-server/v4/adapters/pubnative" + "github.com/prebid/prebid-server/v4/adapters/pubrise" + "github.com/prebid/prebid-server/v4/adapters/pulsepoint" + "github.com/prebid/prebid-server/v4/adapters/pwbid" + "github.com/prebid/prebid-server/v4/adapters/qt" + "github.com/prebid/prebid-server/v4/adapters/readpeak" + "github.com/prebid/prebid-server/v4/adapters/rediads" + "github.com/prebid/prebid-server/v4/adapters/relevantdigital" + "github.com/prebid/prebid-server/v4/adapters/resetdigital" + "github.com/prebid/prebid-server/v4/adapters/revcontent" + "github.com/prebid/prebid-server/v4/adapters/richaudience" + "github.com/prebid/prebid-server/v4/adapters/rise" + "github.com/prebid/prebid-server/v4/adapters/roulax" + "github.com/prebid/prebid-server/v4/adapters/rtbhouse" + "github.com/prebid/prebid-server/v4/adapters/rtbstack" + "github.com/prebid/prebid-server/v4/adapters/rubicon" + salunamedia "github.com/prebid/prebid-server/v4/adapters/sa_lunamedia" + "github.com/prebid/prebid-server/v4/adapters/scalibur" + "github.com/prebid/prebid-server/v4/adapters/seedingAlliance" + "github.com/prebid/prebid-server/v4/adapters/seedtag" + "github.com/prebid/prebid-server/v4/adapters/sharethrough" + "github.com/prebid/prebid-server/v4/adapters/showheroes" + "github.com/prebid/prebid-server/v4/adapters/silvermob" + "github.com/prebid/prebid-server/v4/adapters/silverpush" + "github.com/prebid/prebid-server/v4/adapters/smaato" + "github.com/prebid/prebid-server/v4/adapters/smartadserver" + "github.com/prebid/prebid-server/v4/adapters/smarthub" + "github.com/prebid/prebid-server/v4/adapters/smartrtb" + "github.com/prebid/prebid-server/v4/adapters/smartx" + "github.com/prebid/prebid-server/v4/adapters/smartyads" + "github.com/prebid/prebid-server/v4/adapters/smilewanted" + "github.com/prebid/prebid-server/v4/adapters/smoot" + "github.com/prebid/prebid-server/v4/adapters/smrtconnect" + "github.com/prebid/prebid-server/v4/adapters/sonobi" + "github.com/prebid/prebid-server/v4/adapters/sovrn" + "github.com/prebid/prebid-server/v4/adapters/sovrnXsp" + "github.com/prebid/prebid-server/v4/adapters/sparteo" + "github.com/prebid/prebid-server/v4/adapters/sspBC" + "github.com/prebid/prebid-server/v4/adapters/stackadapt" + "github.com/prebid/prebid-server/v4/adapters/startio" + "github.com/prebid/prebid-server/v4/adapters/stroeerCore" + "github.com/prebid/prebid-server/v4/adapters/synapseHX" + "github.com/prebid/prebid-server/v4/adapters/taboola" + "github.com/prebid/prebid-server/v4/adapters/tadvertising_blis" + "github.com/prebid/prebid-server/v4/adapters/tappx" + "github.com/prebid/prebid-server/v4/adapters/targetVideo" + "github.com/prebid/prebid-server/v4/adapters/teads" + "github.com/prebid/prebid-server/v4/adapters/teal" + "github.com/prebid/prebid-server/v4/adapters/telaria" + "github.com/prebid/prebid-server/v4/adapters/teqblaze" + "github.com/prebid/prebid-server/v4/adapters/theadx" + "github.com/prebid/prebid-server/v4/adapters/thetradedesk" + "github.com/prebid/prebid-server/v4/adapters/tpmn" + "github.com/prebid/prebid-server/v4/adapters/tradplus" + "github.com/prebid/prebid-server/v4/adapters/trafficgate" + "github.com/prebid/prebid-server/v4/adapters/triplelift" + "github.com/prebid/prebid-server/v4/adapters/triplelift_native" + "github.com/prebid/prebid-server/v4/adapters/trustedstack" + "github.com/prebid/prebid-server/v4/adapters/trustx" + "github.com/prebid/prebid-server/v4/adapters/ucfunnel" + "github.com/prebid/prebid-server/v4/adapters/undertone" + "github.com/prebid/prebid-server/v4/adapters/unicorn" + "github.com/prebid/prebid-server/v4/adapters/unruly" + "github.com/prebid/prebid-server/v4/adapters/vidazoo" + "github.com/prebid/prebid-server/v4/adapters/videobyte" + "github.com/prebid/prebid-server/v4/adapters/videoheroes" + "github.com/prebid/prebid-server/v4/adapters/vidoomy" + "github.com/prebid/prebid-server/v4/adapters/visiblemeasures" + "github.com/prebid/prebid-server/v4/adapters/visx" + "github.com/prebid/prebid-server/v4/adapters/vox" + "github.com/prebid/prebid-server/v4/adapters/vrtcal" + "github.com/prebid/prebid-server/v4/adapters/vungle" + "github.com/prebid/prebid-server/v4/adapters/xeworks" + "github.com/prebid/prebid-server/v4/adapters/yahooAds" + "github.com/prebid/prebid-server/v4/adapters/yandex" + "github.com/prebid/prebid-server/v4/adapters/yeahmobi" + "github.com/prebid/prebid-server/v4/adapters/yieldlab" + "github.com/prebid/prebid-server/v4/adapters/yieldmo" + "github.com/prebid/prebid-server/v4/adapters/yieldone" + "github.com/prebid/prebid-server/v4/adapters/zentotem" + "github.com/prebid/prebid-server/v4/adapters/zeroclickfraud" + "github.com/prebid/prebid-server/v4/adapters/zeta_global_ssp" + "github.com/prebid/prebid-server/v4/adapters/zmaticoo" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // Adapter registration is kept in this separate file for ease of use and to aid @@ -287,15 +295,11 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAdmatic: admatic.Builder, openrtb_ext.BidderAdmixer: admixer.Builder, openrtb_ext.BidderAdnuntius: adnuntius.Builder, - openrtb_ext.BidderAdOcean: adocean.Builder, - openrtb_ext.BidderAdoppler: adoppler.Builder, openrtb_ext.BidderAdot: adot.Builder, openrtb_ext.BidderAdpone: adpone.Builder, openrtb_ext.BidderAdprime: adprime.Builder, openrtb_ext.BidderAdquery: adquery.Builder, openrtb_ext.BidderAdrino: adrino.Builder, - openrtb_ext.BidderAdsInteractive: ads_interactive.Builder, - openrtb_ext.BidderAdsinteractive: adsinteractive.Builder, openrtb_ext.BidderAdtarget: adtarget.Builder, openrtb_ext.BidderAdtrgtme: adtrgtme.Builder, openrtb_ext.BidderAdtelligent: adtelligent.Builder, @@ -312,6 +316,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAkcelo: akcelo.Builder, openrtb_ext.BidderAlgorix: algorix.Builder, openrtb_ext.BidderAlkimi: alkimi.Builder, + openrtb_ext.BidderAllianceGravity: alliance_gravity.Builder, openrtb_ext.BidderAMX: amx.Builder, openrtb_ext.BidderApacdex: apacdex.Builder, openrtb_ext.BidderAppnexus: appnexus.Builder, @@ -325,6 +330,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderBeachfront: beachfront.Builder, openrtb_ext.BidderBeintoo: beintoo.Builder, openrtb_ext.BidderBematterfull: bematterfull.Builder, + openrtb_ext.BidderBeop: beop.Builder, openrtb_ext.BidderBetween: between.Builder, openrtb_ext.BidderBeyondMedia: beyondmedia.Builder, openrtb_ext.BidderBidmachine: bidmachine.Builder, @@ -369,15 +375,17 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderDisplayio: displayio.Builder, openrtb_ext.BidderEdge226: edge226.Builder, openrtb_ext.BidderDmx: dmx.Builder, - openrtb_ext.BidderDXKulture: dxkulture.Builder, openrtb_ext.BidderDriftPixel: driftpixel.Builder, + openrtb_ext.BidderElementalTV: elementaltv.Builder, openrtb_ext.BidderEmtv: emtv.Builder, openrtb_ext.BidderEmxDigital: cadentaperturemx.Builder, openrtb_ext.BidderEPlanning: eplanning.Builder, openrtb_ext.BidderEpom: epom.Builder, openrtb_ext.BidderEscalax: escalax.Builder, + openrtb_ext.BidderEskimi: eskimi.Builder, openrtb_ext.BidderExco: exco.Builder, openrtb_ext.BidderEVolution: evolution.Builder, + openrtb_ext.BidderEzoic: ezoic.Builder, openrtb_ext.BidderFeedAd: feedad.Builder, openrtb_ext.BidderFlatads: flatads.Builder, openrtb_ext.BidderFlipp: flipp.Builder, @@ -388,7 +396,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderGamoshi: gamoshi.Builder, openrtb_ext.BidderGlobalsun: globalsun.Builder, openrtb_ext.BidderGoldbach: goldbach.Builder, - openrtb_ext.BidderGothamads: gothamads.Builder, openrtb_ext.BidderGrid: grid.Builder, openrtb_ext.BidderGumGum: gumgum.Builder, openrtb_ext.BidderHuaweiAds: huaweiads.Builder, @@ -398,8 +405,8 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderInfyTV: infytv.Builder, openrtb_ext.BidderInMobi: inmobi.Builder, openrtb_ext.BidderInsticator: insticator.Builder, + openrtb_ext.BidderIntenze: intenze.Builder, openrtb_ext.BidderInteractiveoffers: interactiveoffers.Builder, - openrtb_ext.BidderIntertech: intertech.Builder, openrtb_ext.BidderInvibes: invibes.Builder, openrtb_ext.BidderIQX: iqx.Builder, openrtb_ext.BidderIQZone: iqzone.Builder, @@ -459,7 +466,9 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderOwnAdx: ownadx.Builder, openrtb_ext.BidderPangle: pangle.Builder, openrtb_ext.BidderPGAMSsp: pgamssp.Builder, + openrtb_ext.BidderPixfuture: pixfuture.Builder, openrtb_ext.BidderPlaydigo: playdigo.Builder, + openrtb_ext.BidderProxistore: proxistore.Builder, openrtb_ext.BidderPubmatic: pubmatic.Builder, openrtb_ext.BidderPubnative: pubnative.Builder, openrtb_ext.BidderPubrise: pubrise.Builder, @@ -475,11 +484,12 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderRise: rise.Builder, openrtb_ext.BidderRoulax: roulax.Builder, openrtb_ext.BidderRTBHouse: rtbhouse.Builder, + openrtb_ext.BidderRTBStack: rtbstack.Builder, openrtb_ext.BidderRubicon: rubicon.Builder, openrtb_ext.BidderSeedingAlliance: seedingAlliance.Builder, openrtb_ext.BidderSeedtag: seedtag.Builder, openrtb_ext.BidderSaLunaMedia: salunamedia.Builder, - openrtb_ext.BidderScreencore: screencore.Builder, + openrtb_ext.BidderScalibur: scalibur.Builder, openrtb_ext.BidderSharethrough: sharethrough.Builder, openrtb_ext.BidderShowheroes: showheroes.Builder, openrtb_ext.BidderSilverMob: silvermob.Builder, @@ -498,11 +508,16 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderSovrnXsp: sovrnXsp.Builder, openrtb_ext.BidderSparteo: sparteo.Builder, openrtb_ext.BidderSspBC: sspBC.Builder, + openrtb_ext.BidderStackAdapt: stackadapt.Builder, openrtb_ext.BidderStartIO: startio.Builder, openrtb_ext.BidderStroeerCore: stroeerCore.Builder, + openrtb_ext.BidderSynapseHX: synapseHX.Builder, openrtb_ext.BidderTaboola: taboola.Builder, + openrtb_ext.BidderTAdvertisingBlis: tadvertising_blis.Builder, openrtb_ext.BidderTappx: tappx.Builder, + openrtb_ext.BidderTargetVideo: targetVideo.Builder, openrtb_ext.BidderTeads: teads.Builder, + openrtb_ext.BidderTeal: teal.Builder, openrtb_ext.BidderTelaria: telaria.Builder, openrtb_ext.BidderTeqBlaze: teqblaze.Builder, openrtb_ext.BidderTheadx: theadx.Builder, @@ -513,6 +528,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderTriplelift: triplelift.Builder, openrtb_ext.BidderTripleliftNative: triplelift_native.Builder, openrtb_ext.BidderTrustedstack: trustedstack.Builder, + openrtb_ext.BidderTrustX: trustx.Builder, openrtb_ext.BidderUcfunnel: ucfunnel.Builder, openrtb_ext.BidderUndertone: undertone.Builder, openrtb_ext.BidderUnicorn: unicorn.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index fb47a9e458..fbc87b08ae 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -5,10 +5,10 @@ import ( "net/http" "strings" - "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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func BuildAdapters(client *http.Client, cfg *config.Configuration, infos config.BidderInfos, me metrics.MetricsEngine) (map[openrtb_ext.BidderName]AdaptedBidder, map[openrtb_ext.BidderName]struct{}, []error) { @@ -128,6 +128,13 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin "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.`, + "gothamads": `Bidder "gothamads" is no longer available in Prebid Server. Please rename it to "intenze" in your configuration.`, + "intertech": `Bidder "intertech" is no longer available in Prebid Server. Please update your configuration.`, + "adocean": `Bidder "adocean" is no longer available in Prebid Server. Please update your configuration.`, + "dxkulture": `Bidder "dxkulture" is no longer available in Prebid Server. Please update your configuration.`, + "mobupps": `Bidder "mobupps" is no longer available in Prebid Server. Please update your configuration.`, + "vimayx": `Bidder "vimayx" is no longer available in Prebid Server. Please update your configuration.`, + "adoppler": `Bidder "adoppler" is no longer available in Prebid Server. If you're looking to use the Adoppler adapter, please rename it to "elementaltv" in your configuration.`, } return mergeRemovedAndDisabledBidderWarningMessages(removed, infos) diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go index 9827758356..cf06957d8c 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/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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adapters/appnexus" + "github.com/prebid/prebid-server/v4/adapters/rubicon" + "github.com/prebid/prebid-server/v4/config" + metrics "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/exchange/auction.go b/exchange/auction.go index ff1e28302c..6a5cc8b280 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/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/v4/config" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/prebid_cache_client" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const ( diff --git a/exchange/auction_response.go b/exchange/auction_response.go index 67ab2dc4bb..592e89eaa6 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 188e4d30ea..95ee6d3710 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/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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/prebid_cache_client" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/exchange/bidder.go b/exchange/bidder.go index 264a03d46e..87d3eaa719 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -19,25 +19,25 @@ import ( "sync/atomic" "time" - "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" - loggerI "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/version" + "github.com/prebid/prebid-server/v4/bidadjustment" + "github.com/prebid/prebid-server/v4/config/util" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/experiment/adscert" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + loggerI "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/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/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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "golang.org/x/net/context/ctxhttp" ) @@ -616,7 +616,7 @@ func (bidder *BidderAdapter) doRequestImpl(ctx context.Context, req *adapters.Re httpResp, err := ctxhttp.Do(ctx, bidder.Client, httpReq) if err != nil { bidder.logHealthCheck(false) - if err == context.DeadlineExceeded { + if errors.Is(err, context.DeadlineExceeded) { err = &errortypes.Timeout{Message: err.Error()} var corebidder adapters.Bidder = bidder.Bidder // The bidder adapter normally stores an info-aware bidder (a bidder wrapper) @@ -631,7 +631,6 @@ func (bidder *BidderAdapter) doRequestImpl(ctx context.Context, req *adapters.Re // a loop of trying to report timeouts to the timeout notifications. go bidder.doTimeoutNotification(tb, req, logger) } - } return &httpCallInfo{ request: req, diff --git a/exchange/bidder_health_test.go b/exchange/bidder_health_test.go index 1fa7748923..0bf46b5afc 100644 --- a/exchange/bidder_health_test.go +++ b/exchange/bidder_health_test.go @@ -6,9 +6,9 @@ import ( "sync" "testing" - "github.com/prebid/prebid-server/v3/metrics" - "github.com/prebid/prebid-server/v3/metrics/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index eb061ee691..3fd7f51300 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -25,20 +25,20 @@ 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/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/logger" - "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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/experiment/adscert" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" + metricsConfig "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" + "github.com/prebid/prebid-server/v4/version" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/exchange/bidder_validate_bids.go b/exchange/bidder_validate_bids.go index 5c5da548cb..c4541a3a7d 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/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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/experiment/adscert" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/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 b611ca8175..777c0a504f 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/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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/experiment/adscert" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/exchange/entities/entities.go b/exchange/entities/entities.go index 808125f1c1..cb5b6c4cdf 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // PbsOrtbSeatBid is a SeatBid returned by an AdaptedBidder. diff --git a/exchange/events.go b/exchange/events.go index 20150f90b9..75334f6c5d 100644 --- a/exchange/events.go +++ b/exchange/events.go @@ -3,14 +3,14 @@ package exchange import ( "time" - "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v4/exchange/entities" jsonpatch "gopkg.in/evanphx/json-patch.v5" - "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" + "github.com/prebid/prebid-server/v4/analytics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/endpoints/events" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 3f35ef517d..e8ac475150 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/v3/exchange/entities" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/exchange/exchange.go b/exchange/exchange.go index ef24e3fc9c..1452c04928 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -14,31 +14,31 @@ import ( "strings" "time" - "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/logger" - "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/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" - "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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/adservertargeting" + "github.com/prebid/prebid-server/v4/bidadjustment" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/dsa" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/experiment/adscert" + "github.com/prebid/prebid-server/v4/firstpartydata" + "github.com/prebid/prebid-server/v4/floors" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/prebid_cache_client" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_responses" + "github.com/prebid/prebid-server/v4/usersync" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/maputil" "github.com/buger/jsonparser" "github.com/gofrs/uuid" diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 0a41e6ac0f..7770a2ec34 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/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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/experiment/adscert" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/metrics" + metricsConf "github.com/prebid/prebid-server/v4/metrics/config" + metricsConfig "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/ortb" + pbc "github.com/prebid/prebid-server/v4/prebid_cache_client" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests/backends/file_fetcher" + "github.com/prebid/prebid-server/v4/stored_responses" + "github.com/prebid/prebid-server/v4/usersync" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" jsonpatch "gopkg.in/evanphx/json-patch.v5" @@ -5996,7 +5996,7 @@ func (e mockUpdateBidRequestHook) HandleBidderRequestHook(_ context.Context, mct }, hookstage.MutationUpdate, "bidRequest", "site.domain", ) - mctx.ModuleContext = map[string]interface{}{"some-ctx": "some-ctx"} + mctx.ModuleContext.Set("some-ctx", "some-ctx") return hookstage.HookResult[hookstage.BidderRequestPayload]{ChangeSet: c, ModuleContext: mctx.ModuleContext}, nil } diff --git a/exchange/msp_bidders.go b/exchange/msp_bidders.go index 359d7615c3..209d0bd35b 100644 --- a/exchange/msp_bidders.go +++ b/exchange/msp_bidders.go @@ -2,11 +2,11 @@ package exchange import ( "github.com/golang/glog" - "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/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" - mspPlugin "github.com/prebid/prebid-server/v3/msp/plugin" + mspPlugin "github.com/prebid/prebid-server/v4/msp/plugin" ) type PluginBuilder interface { diff --git a/exchange/non_bid_reason.go b/exchange/non_bid_reason.go index 05d4ea3ee6..04f18d9c86 100644 --- a/exchange/non_bid_reason.go +++ b/exchange/non_bid_reason.go @@ -5,7 +5,7 @@ import ( "net" "syscall" - "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v4/errortypes" ) // SeatNonBid list the reasons why bid was not resulted in positive bid diff --git a/exchange/non_bid_reason_test.go b/exchange/non_bid_reason_test.go index fb9c5e434f..5c30dde969 100644 --- a/exchange/non_bid_reason_test.go +++ b/exchange/non_bid_reason_test.go @@ -6,7 +6,7 @@ import ( "syscall" "testing" - "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v4/errortypes" "github.com/stretchr/testify/assert" ) diff --git a/exchange/price_granularity.go b/exchange/price_granularity.go index b1d5073cd3..d471085dbb 100644 --- a/exchange/price_granularity.go +++ b/exchange/price_granularity.go @@ -6,8 +6,8 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/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 277696b88d..ca18d7ae78 100644 --- a/exchange/price_granularity_test.go +++ b/exchange/price_granularity_test.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/exchange/seat_non_bids.go b/exchange/seat_non_bids.go index fd6fd1da3f..d62dcb7f81 100644 --- a/exchange/seat_non_bids.go +++ b/exchange/seat_non_bids.go @@ -1,8 +1,8 @@ package exchange import ( - "github.com/prebid/prebid-server/v3/exchange/entities" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type SeatNonBidBuilder map[string][]openrtb_ext.NonBid diff --git a/exchange/seat_non_bids_test.go b/exchange/seat_non_bids_test.go index 4a8f9e8f78..a6ec99fb10 100644 --- a/exchange/seat_non_bids_test.go +++ b/exchange/seat_non_bids_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/exchange/entities" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/exchange/targeting.go b/exchange/targeting.go index d39c2cba0a..468f42d457 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const MaxKeyLength = 20 diff --git a/exchange/targeting_test.go b/exchange/targeting_test.go index 7fe26c4bad..a3625ab3ad 100644 --- a/exchange/targeting_test.go +++ b/exchange/targeting_test.go @@ -8,16 +8,16 @@ import ( "testing" "time" - "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/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + metricsConfig "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/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 0d0fa31fdc..7fe69b3906 100644 --- a/exchange/tmax_adjustments.go +++ b/exchange/tmax_adjustments.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v4/config" ) type TmaxAdjustmentsPreprocessed struct { diff --git a/exchange/tmax_adjustments_test.go b/exchange/tmax_adjustments_test.go index 7925233987..6a3041c0a5 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/v3/config" + "github.com/prebid/prebid-server/v4/config" "github.com/stretchr/testify/assert" ) diff --git a/exchange/utils.go b/exchange/utils.go index 7606cd4248..ce590dd057 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -13,20 +13,20 @@ import ( gppConstants "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v20/openrtb2" - "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" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/firstpartydata" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/privacy/ccpa" + "github.com/prebid/prebid-server/v4/privacy/lmt" + "github.com/prebid/prebid-server/v4/schain" + "github.com/prebid/prebid-server/v4/stored_responses" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) var errInvalidRequestExt = errors.New("request.ext is invalid") @@ -157,6 +157,7 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, reqWrapperCopy := req.CloneAndClearImpWrappers() bidRequestCopy := *req.BidRequest reqWrapperCopy.BidRequest = &bidRequestCopy + reqWrapperCopy.Imp = imps coreBidder, isRequestAlias := resolveBidder(bidder, requestAliases) @@ -848,11 +849,14 @@ func removeUnpermissionedEids(reqWrapper *openrtb_ext.RequestWrapper, bidder str return nil } + // clone User before mutating EIDs to avoid corrupting the shared pointer + userCopy := *reqWrapper.User if len(eidsAllowed) == 0 { - reqWrapper.User.EIDs = nil + userCopy.EIDs = nil } else { - reqWrapper.User.EIDs = eidsAllowed + userCopy.EIDs = eidsAllowed } + reqWrapper.User = &userCopy return nil } diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 3585c71be3..71938e102f 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -10,15 +10,15 @@ import ( gpplib "github.com/prebid/go-gpp" "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v20/openrtb2" - "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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/firstpartydata" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -3143,10 +3143,138 @@ func TestRemoveUnpermissionedEids(t *testing.T) { User: &openrtb2.User{EIDs: test.expectedUserEids}, } + originalUser := reqWrapper.User + resultErr := removeUnpermissionedEids(&reqWrapper, bidder) assert.NoError(t, resultErr, test.description) assert.Equal(t, expectedRequest, reqWrapper.BidRequest) + + eidsRemoved := len(test.userEids) > 0 && len(test.expectedUserEids) != len(test.userEids) + if eidsRemoved { + assert.NotSame(t, originalUser, reqWrapper.User, "User must be cloned when EIDs are removed to avoid corrupting shared state") + } + }) + } +} + +// TestCleanOpenRTBRequestsEidPermissionsRaceCondition is a regression test for issue #4792. +// +// cleanOpenRTBRequests splits a single request into per-bidder requests with a +// shallow struct copy (bidRequestCopy := *req.BidRequest). Because User is a +// pointer, every per-bidder copy used to share the same *openrtb2.User, and +// removeUnpermissionedEids mutated User.EIDs in place. The result was that a +// permitted bidder could intermittently lose its EID depending on Go map +// iteration order (the order bidders are processed in the impsByBidder loop). +// +// This test runs cleanOpenRTBRequests many times so the map iteration order +// varies, and asserts the permitted bidder ALWAYS retains the EID while +// non-permitted bidders ALWAYS have it stripped. +func TestCleanOpenRTBRequestsEidPermissionsRaceCondition(t *testing.T) { + const ( + permittedBidder = "bidderA" + eidSource = "source1" + iterations = 10 + ) + permittedBidders := []string{permittedBidder} + deniedBidders := []string{"bidderB", "bidderC"} + + buildAuctionRequest := func() AuctionRequest { + bidRequest := &openrtb2.BidRequest{ + ID: "race-cond", + User: &openrtb2.User{ + EIDs: []openrtb2.EID{ + {Source: eidSource, UIDs: []openrtb2.UID{{ID: "shared-id", AType: 1}}}, + }, + }, + Imp: []openrtb2.Imp{ + { + ID: "imp-1", + Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}, + Ext: json.RawMessage(`{"prebid":{"bidder":{` + + `"bidderA":{"placementId":"1"},` + + `"bidderB":{"placementId":"2"},` + + `"bidderC":{"placementId":"3"}}}}`), + }, + }, + } + + reqWrapper := &openrtb_ext.RequestWrapper{BidRequest: bidRequest} + reqExt, err := reqWrapper.GetRequestExt() + require.NoError(t, err) + reqExt.SetPrebid(&openrtb_ext.ExtRequestPrebid{ + Data: &openrtb_ext.ExtRequestPrebidData{ + EidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ + {Source: eidSource, Bidders: []string{permittedBidder}}, + }, + }, }) + require.NoError(t, reqWrapper.RebuildRequest()) + + return AuctionRequest{ + BidRequestWrapper: reqWrapper, + UserSyncs: &emptyUsersync{}, + TCF2Config: gdpr.NewTCF2Config(config.TCF2{}, config.AccountGDPR{}), + } + } + + gdprPermissionsBuilder := fakePermissionsBuilder{ + permissions: &permissionsMock{ + allowAllBidders: true, + }, + }.Builder + + // Mark all bidders as ORTB 2.6 so their EIDs stay in user.eids instead of + // being down-converted into user.ext.eids, keeping the assertion simple. + bidderInfo := config.BidderInfos{ + permittedBidder: {OpenRTB: &config.OpenRTBInfo{Version: "2.6"}}, + } + for _, b := range deniedBidders { + bidderInfo[b] = config.BidderInfo{OpenRTB: &config.OpenRTBInfo{Version: "2.6"}} + } + + eidSources := func(user *openrtb2.User) []string { + if user == nil { + return nil + } + sources := make([]string, 0, len(user.EIDs)) + for _, eid := range user.EIDs { + sources = append(sources, eid.Source) + } + return sources + } + + for i := 0; i < iterations; i++ { + reqSplitter := &requestSplitter{ + bidderToSyncerKey: map[string]string{}, + me: &metrics.MetricsEngineMock{}, + privacyConfig: config.Privacy{}, + gdprPermsBuilder: gdprPermissionsBuilder, + hostSChainNode: nil, + bidderInfo: bidderInfo, + } + + bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), buildAuctionRequest(), nil, map[string]float64{}) + require.Empty(t, errs, "iteration %d returned errors", i) + require.Len(t, bidderRequests, len(permittedBidders)+len(deniedBidders), "iteration %d produced unexpected number of bidder requests", i) + + seen := make(map[string]bool, len(bidderRequests)) + for _, br := range bidderRequests { + bidder := string(br.BidderName) + seen[bidder] = true + sources := eidSources(br.BidRequest.User) + if bidder == permittedBidder { + assert.Contains(t, sources, eidSource, + "iteration %d: permitted bidder %q must retain EID %q (sources=%v)", i, bidder, eidSource, sources) + } else { + assert.NotContains(t, sources, eidSource, + "iteration %d: non-permitted bidder %q must not receive EID %q (sources=%v)", i, bidder, eidSource, sources) + } + } + + assert.True(t, seen[permittedBidder], "iteration %d: permitted bidder %q missing from results", i, permittedBidder) + for _, b := range deniedBidders { + assert.True(t, seen[b], "iteration %d: bidder %q missing from results", i, b) + } } } diff --git a/experiment/adscert/SignerLogger.go b/experiment/adscert/SignerLogger.go index 798e9bd2a1..d2ba706e82 100644 --- a/experiment/adscert/SignerLogger.go +++ b/experiment/adscert/SignerLogger.go @@ -3,7 +3,7 @@ package adscert import ( "fmt" - "github.com/prebid/prebid-server/v3/logger" + "github.com/prebid/prebid-server/v4/logger" ) type SignerLogger struct { diff --git a/experiment/adscert/inprocesssigner.go b/experiment/adscert/inprocesssigner.go index ee5f4905d2..a8d0ac7244 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/v3/config" + "github.com/prebid/prebid-server/v4/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 c441bbebb6..0576d39976 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/v3/config" + "github.com/prebid/prebid-server/v4/config" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) diff --git a/experiment/adscert/signer.go b/experiment/adscert/signer.go index f7ea9a4254..44003cd88c 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/v3/config" + "github.com/prebid/prebid-server/v4/config" ) const SignHeader = "X-Ads-Cert-Auth" diff --git a/experiment/adscert/signer_test.go b/experiment/adscert/signer_test.go index 3e08d0f6ba..596922be34 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/v3/config" + "github.com/prebid/prebid-server/v4/config" "github.com/stretchr/testify/assert" ) diff --git a/firstpartydata/first_party_data.go b/firstpartydata/first_party_data.go index c91a0689b8..44a451600a 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.v5" - "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/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) var ( diff --git a/firstpartydata/first_party_data_test.go b/firstpartydata/first_party_data_test.go index 3e4ff174ee..ef88e79a59 100644 --- a/firstpartydata/first_party_data_test.go +++ b/firstpartydata/first_party_data_test.go @@ -8,9 +8,9 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "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/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/floors/enforce.go b/floors/enforce.go index f72d2bb72c..f55d80e07c 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/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/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/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 3da86e2d74..c839188d7b 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/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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/floors/fetcher.go b/floors/fetcher.go index c3d2a02f78..ac62931a39 100644 --- a/floors/fetcher.go +++ b/floors/fetcher.go @@ -14,11 +14,11 @@ import ( "github.com/alitto/pond" validator "github.com/asaskevich/govalidator" "github.com/coocood/freecache" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/metrics" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/timeutil" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/timeutil" ) var refetchCheckInterval = 300 diff --git a/floors/fetcher_test.go b/floors/fetcher_test.go index 83876dc48b..41bff4e2ad 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/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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + metricsConf "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/timeutil" "github.com/stretchr/testify/assert" ) diff --git a/floors/floors.go b/floors/floors.go index 5bcd2e5e62..658bf756ec 100644 --- a/floors/floors.go +++ b/floors/floors.go @@ -6,10 +6,10 @@ import ( "math/rand" "strings" - "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" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) type Price struct { diff --git a/floors/floors_test.go b/floors/floors_test.go index 8d73a5de0a..fecdad24c5 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/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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/floors/rule.go b/floors/rule.go index fb3130c609..4e85328878 100644 --- a/floors/rule.go +++ b/floors/rule.go @@ -8,10 +8,10 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/currency" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) const ( diff --git a/floors/rule_test.go b/floors/rule_test.go index dc46e05993..d5d65f0e2f 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/v3/currency" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/floors/validate.go b/floors/validate.go index 140df7def3..74db164062 100644 --- a/floors/validate.go +++ b/floors/validate.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) var validSchemaDimensions = map[string]struct{}{ diff --git a/floors/validate_test.go b/floors/validate_test.go index 36c1c73e0b..37418ea5eb 100644 --- a/floors/validate_test.go +++ b/floors/validate_test.go @@ -5,8 +5,8 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/aggregated_config.go b/gdpr/aggregated_config.go index 3df5fdc7ff..c0f40f4a6d 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/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/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 f577772cb6..44cd07efcf 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/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/basic_enforcement_test.go b/gdpr/basic_enforcement_test.go index 7bb0076940..b4ed2aeb3d 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/full_enforcement_test.go b/gdpr/full_enforcement_test.go index eed86bf238..10c8463f37 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/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/gdpr.go b/gdpr/gdpr.go index 26e04e0b95..633741a752 100644 --- a/gdpr/gdpr.go +++ b/gdpr/gdpr.go @@ -3,9 +3,9 @@ package gdpr import ( "context" - "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/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type Permissions interface { @@ -35,16 +35,16 @@ type RequestInfo struct { } // NewPermissionsBuilder takes host config data used to configure the builder function it returns -func NewPermissionsBuilder(cfg config.GDPR, gvlVendorIDs map[openrtb_ext.BidderName]uint16, vendorListFetcher VendorListFetcher, me metrics.MetricsEngine) PermissionsBuilder { +func NewPermissionsBuilder(cfg config.GDPR, gvlVendorIDs map[openrtb_ext.BidderName]uint16, validGVLVendorIDs *LiveGVLVendorIDs, vendorListFetcher VendorListFetcher, me metrics.MetricsEngine) PermissionsBuilder { return func(tcf2Cfg TCF2ConfigReader, requestInfo RequestInfo) Permissions { purposeEnforcerBuilder := NewPurposeEnforcerBuilder(tcf2Cfg) - return NewPermissions(cfg, tcf2Cfg, gvlVendorIDs, vendorListFetcher, purposeEnforcerBuilder, requestInfo, me) + return NewPermissions(cfg, tcf2Cfg, gvlVendorIDs, validGVLVendorIDs, vendorListFetcher, purposeEnforcerBuilder, requestInfo, me) } } // NewPermissions gets a per-request Permissions object that can then be used to check GDPR permissions for a given bidder. -func NewPermissions(cfg config.GDPR, tcf2Config TCF2ConfigReader, vendorIDs map[openrtb_ext.BidderName]uint16, fetcher VendorListFetcher, purposeEnforcerBuilder PurposeEnforcerBuilder, requestInfo RequestInfo, metricsEngine metrics.MetricsEngine) Permissions { +func NewPermissions(cfg config.GDPR, tcf2Config TCF2ConfigReader, vendorIDs map[openrtb_ext.BidderName]uint16, validGVLVendorIDs *LiveGVLVendorIDs, fetcher VendorListFetcher, purposeEnforcerBuilder PurposeEnforcerBuilder, requestInfo RequestInfo, metricsEngine metrics.MetricsEngine) Permissions { if !cfg.Enabled { return &AlwaysAllow{} } @@ -55,6 +55,7 @@ func NewPermissions(cfg config.GDPR, tcf2Config TCF2ConfigReader, vendorIDs map[ hostVendorID: cfg.HostVendorID, nonStandardPublishers: cfg.NonStandardPublisherMap, cfg: tcf2Config, + validGVLVendorIDs: validGVLVendorIDs, vendorIDs: vendorIDs, publisherID: requestInfo.PublisherID, gdprSignal: SignalNormalize(requestInfo.GDPRSignal, cfg.DefaultValue), diff --git a/gdpr/gdpr_test.go b/gdpr/gdpr_test.go index 6329dad858..6670fc6849 100644 --- a/gdpr/gdpr_test.go +++ b/gdpr/gdpr_test.go @@ -6,9 +6,9 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/go-gdpr/vendorlist" - "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/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -51,7 +51,7 @@ func TestNewPermissions(t *testing.T) { fakePurposeEnforcerBuilder := fakePurposeEnforcerBuilder{ purposeEnforcer: nil, }.Builder - perms := NewPermissions(config, &tcf2Config{}, vendorIDs, vendorListFetcher, fakePurposeEnforcerBuilder, RequestInfo{}, &metrics.MetricsEngineMock{}) + perms := NewPermissions(config, &tcf2Config{}, vendorIDs, nil, vendorListFetcher, fakePurposeEnforcerBuilder, RequestInfo{}, &metrics.MetricsEngineMock{}) assert.IsType(t, tt.wantType, perms, tt.description) } diff --git a/gdpr/gvl_vendor_ids.go b/gdpr/gvl_vendor_ids.go new file mode 100644 index 0000000000..bcec2db517 --- /dev/null +++ b/gdpr/gvl_vendor_ids.go @@ -0,0 +1,119 @@ +package gdpr + +import ( + "context" + "encoding/json" + "io" + "net/http" + "sync/atomic" + "time" + + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/util/task" + "golang.org/x/net/context/ctxhttp" +) + +// LiveGVLVendorIDs provides thread-safe access to the set of vendor IDs present in the latest +// Global Vendor List. It uses atomic.Value so reads (on every request) are lock-free, while +// writes (periodic refresh) are safe without mutexes. +type LiveGVLVendorIDs struct { + ids atomic.Value // holds map[uint16]struct{} +} + +// NewLiveGVLVendorIDs creates a LiveGVLVendorIDs initialized with an empty set. +func NewLiveGVLVendorIDs() *LiveGVLVendorIDs { + l := &LiveGVLVendorIDs{} + l.ids.Store(make(map[uint16]struct{})) + return l +} + +// Contains returns true if the given vendor ID is in the current valid set. +// If the set is empty (e.g. the GVL fetch failed), all IDs are considered valid +// as a safe fallback. +func (l *LiveGVLVendorIDs) Contains(id uint16) bool { + m := l.ids.Load().(map[uint16]struct{}) + if len(m) == 0 { + return true + } + _, ok := m[id] + return ok +} + +// Update atomically replaces the valid vendor ID set. If newIDs is empty, the existing +// set is retained. +func (l *LiveGVLVendorIDs) Update(newIDs map[uint16]struct{}) { + if len(newIDs) > 0 { + l.ids.Store(newIDs) + } +} + +// NewGVLVendorIDTickerTask creates a TickerTask that fetches the latest GVL vendor IDs and +// updates the LiveGVLVendorIDs set. Calling Start on the returned task performs the initial +// fetch immediately and then schedules periodic refreshes at the given interval. +func NewGVLVendorIDTickerTask(interval time.Duration, client *http.Client, urlMaker func(uint16, uint16) string, live *LiveGVLVendorIDs, me metrics.MetricsEngine) *task.TickerTask { + return task.NewTickerTaskFromFunc(interval, func() error { + newIDs := FetchLatestGVLVendorIDs(context.Background(), client, urlMaker, me) + live.Update(newIDs) + return nil + }) +} + +// gvlVendorListContract is a lightweight contract for parsing only vendor IDs from GVL JSON +type gvlVendorListContract struct { + Vendors map[string]struct { + ID uint16 `json:"id"` + } `json:"vendors"` +} + +// FetchLatestGVLVendorIDs fetches the most recent Global Vendor List and returns a set of all +// vendor IDs present in it. The returned map has vendor IDs as keys and empty structs as values. +// If the fetch or parse fails, an empty map is returned. +func FetchLatestGVLVendorIDs(ctx context.Context, client *http.Client, urlMaker func(uint16, uint16) string, me metrics.MetricsEngine) map[uint16]struct{} { + vendorIDs := make(map[uint16]struct{}) + + // Fetch latest GVL for the latest spec version (listVersion 0 means latest) + url := urlMaker(latestSpecVersion, 0) + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + logger.Errorf("Failed to build GET %s request for GVL vendor ID extraction: %v", url, err) + me.RecordLiveGVLFetch(false) + return vendorIDs + } + + resp, err := ctxhttp.Do(ctx, client, req) + if err != nil { + logger.Errorf("Error calling GET %s for GVL vendor ID extraction: %v", url, err) + me.RecordLiveGVLFetch(false) + return vendorIDs + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + logger.Errorf("GET %s returned %d for GVL vendor ID extraction", url, resp.StatusCode) + me.RecordLiveGVLFetch(false) + return vendorIDs + } + + respBody, err := io.ReadAll(resp.Body) + if err != nil { + logger.Errorf("Error reading response body from GET %s for GVL vendor ID extraction: %v", url, err) + me.RecordLiveGVLFetch(false) + return vendorIDs + } + + var contract gvlVendorListContract + if err := json.Unmarshal(respBody, &contract); err != nil { + logger.Errorf("GET %s returned malformed JSON for GVL vendor ID extraction: %v", url, err) + me.RecordLiveGVLFetch(false) + return vendorIDs + } + + for _, v := range contract.Vendors { + vendorIDs[v.ID] = struct{}{} + } + + me.RecordLiveGVLFetch(true) + return vendorIDs +} diff --git a/gdpr/gvl_vendor_ids_test.go b/gdpr/gvl_vendor_ids_test.go new file mode 100644 index 0000000000..43010df578 --- /dev/null +++ b/gdpr/gvl_vendor_ids_test.go @@ -0,0 +1,169 @@ +package gdpr + +import ( + "context" + "net/http" + "net/http/httptest" + "testing" + + "github.com/prebid/prebid-server/v4/metrics" + "github.com/stretchr/testify/assert" +) + +func TestFetchLatestGVLVendorIDs(t *testing.T) { + tests := []struct { + name string + settings serverSettings + expectedIDs map[uint16]struct{} + expectError bool + }{ + { + name: "fetch-with-multiple-vendors", + settings: serverSettings{ + vendorListLatestVersion: 1, + vendorLists: map[int]map[int]string{ + 3: { + 1: MarshalVendorList(vendorList{ + GVLSpecificationVersion: 3, + VendorListVersion: 1, + Vendors: map[string]*vendor{ + "10": {ID: 10}, + "20": {ID: 20}, + "100": {ID: 100}, + }, + }), + }, + }, + }, + expectedIDs: map[uint16]struct{}{ + 10: {}, + 20: {}, + 100: {}, + }, + }, + { + name: "fetch-with-no-vendors", + settings: serverSettings{ + vendorListLatestVersion: 1, + vendorLists: map[int]map[int]string{ + 3: { + 1: MarshalVendorList(vendorList{ + GVLSpecificationVersion: 3, + VendorListVersion: 1, + Vendors: map[string]*vendor{}, + }), + }, + }, + }, + expectedIDs: map[uint16]struct{}{}, + }, + { + name: "error-spec-v3-not-available", + settings: serverSettings{ + vendorListLatestVersion: 1, + vendorLists: map[int]map[int]string{ + 2: { + 1: MarshalVendorList(vendorList{ + GVLSpecificationVersion: 2, + VendorListVersion: 1, + Vendors: map[string]*vendor{"5": {ID: 5}}, + }), + }, + }, + }, + expectedIDs: map[uint16]struct{}{}, + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(mockServer(tt.settings))) + defer server.Close() + + m := &metrics.MetricsEngineMock{} + if tt.expectError { + m.On("RecordLiveGVLFetch", false).Once() + } else { + m.On("RecordLiveGVLFetch", true).Once() + } + result := FetchLatestGVLVendorIDs(context.Background(), server.Client(), testURLMaker(server), m) + assert.Equal(t, tt.expectedIDs, result) + m.AssertExpectations(t) + }) + } +} + +func TestFetchLatestGVLVendorIDsServerError(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + })) + defer server.Close() + + m := &metrics.MetricsEngineMock{} + m.On("RecordLiveGVLFetch", false).Once() + result := FetchLatestGVLVendorIDs(context.Background(), server.Client(), testURLMaker(server), m) + assert.Empty(t, result) + m.AssertExpectations(t) +} + +func TestFetchLatestGVLVendorIDsMalformedJSON(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte("not valid json")) + })) + defer server.Close() + + m := &metrics.MetricsEngineMock{} + m.On("RecordLiveGVLFetch", false).Once() + result := FetchLatestGVLVendorIDs(context.Background(), server.Client(), testURLMaker(server), m) + assert.Empty(t, result) + m.AssertExpectations(t) +} + +func TestLiveGVLVendorIDsContains(t *testing.T) { + tests := []struct { + name string + ids map[uint16]struct{} + checkID uint16 + expected bool + }{ + { + name: "empty-set-returns-true-for-any-id", + ids: map[uint16]struct{}{}, + checkID: 42, + expected: true, + }, + { + name: "id-present-in-set", + ids: map[uint16]struct{}{10: {}, 20: {}}, + checkID: 10, + expected: true, + }, + { + name: "id-not-present-in-set", + ids: map[uint16]struct{}{10: {}, 20: {}}, + checkID: 30, + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + live := NewLiveGVLVendorIDs() + live.Update(tt.ids) + assert.Equal(t, tt.expected, live.Contains(tt.checkID)) + }) + } +} + +func TestLiveGVLVendorIDsUpdateSkipsEmpty(t *testing.T) { + live := NewLiveGVLVendorIDs() + live.Update(map[uint16]struct{}{10: {}, 20: {}}) + + // Updating with empty should retain previous set + live.Update(map[uint16]struct{}{}) + assert.True(t, live.Contains(10)) + assert.True(t, live.Contains(20)) + assert.False(t, live.Contains(30)) +} diff --git a/gdpr/impl.go b/gdpr/impl.go index 24c5b3010e..03c0e234b3 100644 --- a/gdpr/impl.go +++ b/gdpr/impl.go @@ -6,8 +6,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/v3/metrics" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const noBidder openrtb_ext.BidderName = "" @@ -23,6 +23,7 @@ type permissionsImpl struct { metrics metrics.MetricsEngine nonStandardPublishers map[string]struct{} purposeEnforcerBuilder PurposeEnforcerBuilder + validGVLVendorIDs *LiveGVLVendorIDs vendorIDs map[openrtb_ext.BidderName]uint16 // request-specific aliasGVLIDs map[string]uint16 @@ -48,7 +49,7 @@ func (p *permissionsImpl) BidderSyncAllowed(ctx context.Context, bidder openrtb_ } id, ok := p.vendorIDs[bidder] - if ok { + if ok && p.isValidVendorID(id) { vendorExceptions := p.cfg.PurposeVendorExceptions(consentconstants.Purpose(1)) _, vendorException := vendorExceptions[string(bidder)] return p.allowSync(ctx, id, bidder, vendorException) @@ -107,17 +108,34 @@ func (p *permissionsImpl) defaultPermissions() AuctionPermissions { } // resolveVendorID gets the vendor ID for the specified bidder from either the alias GVL IDs -// provided in the request or from the bidder configs loaded at startup +// provided in the request or from the bidder configs loaded at startup. If the resolved ID +// is not present in the latest Global Vendor List, it returns 0 and false. func (p *permissionsImpl) resolveVendorID(bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (id uint16, ok bool) { if id, ok = p.aliasGVLIDs[string(bidder)]; ok { + if !p.isValidVendorID(id) { + return 0, false + } return id, ok } id, ok = p.vendorIDs[bidderCoreName] + if ok && !p.isValidVendorID(id) { + return 0, false + } return id, ok } +// isValidVendorID checks whether the given vendor ID exists in the latest Global Vendor List. +// If the valid set is nil (e.g. the GVL fetch failed), all IDs are considered valid +// as a safe fallback. +func (p *permissionsImpl) isValidVendorID(id uint16) bool { + if p.validGVLVendorIDs == nil { + return true + } + return p.validGVLVendorIDs.Contains(id) +} + // allowSync computes cookie sync activity legal basis for a given bidder using the enforcement // algorithms selected by the purpose enforcer builder func (p *permissionsImpl) allowSync(ctx context.Context, vendorID uint16, bidder openrtb_ext.BidderName, vendorException bool) (bool, error) { diff --git a/gdpr/impl_test.go b/gdpr/impl_test.go index 60a688fcc4..ec62f73108 100644 --- a/gdpr/impl_test.go +++ b/gdpr/impl_test.go @@ -9,9 +9,9 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/go-gdpr/vendorlist" "github.com/prebid/go-gdpr/vendorlist2" - "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/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -1321,6 +1321,94 @@ func TestDefaultPermissions(t *testing.T) { } } +func TestIsValidVendorID(t *testing.T) { + vendor2AndPurpose1Consent := "CPGWbY_PGWbY_GYAAAENABCAAIAAAAAAAAAAACEAAAAA" + vendor2AndPurpose2Consent := "CPGWbY_PGWbY_GYAAAENABCAAEAAAAAAAAAAACEAAAAA" + vendorListData := MarshalVendorList(vendorList{ + VendorListVersion: 2, + Vendors: map[string]*vendor{ + "2": { + ID: 2, + Purposes: []int{1, 2}, + }, + }, + }) + + tcf2AggConfig := allPurposesEnabledTCF2Config() + + tests := []struct { + name string + validGVLVendorIDs *LiveGVLVendorIDs + consent string + expectedAllowSync bool + expectedAllowBidReq bool + expectedPassID bool + }{ + { + name: "nil-live-gvl-vendor-ids", + validGVLVendorIDs: nil, + consent: vendor2AndPurpose1Consent, + expectedAllowSync: true, + expectedAllowBidReq: false, + expectedPassID: false, + }, + { + name: "vendor-id-in-live-gvl", + validGVLVendorIDs: func() *LiveGVLVendorIDs { + l := NewLiveGVLVendorIDs() + l.Update(map[uint16]struct{}{2: {}}) + return l + }(), + consent: vendor2AndPurpose2Consent, + expectedAllowSync: false, + expectedAllowBidReq: true, + expectedPassID: true, + }, + { + name: "vendor-id-not-in-live-gvl", + validGVLVendorIDs: func() *LiveGVLVendorIDs { + l := NewLiveGVLVendorIDs() + l.Update(map[uint16]struct{}{99: {}}) + return l + }(), + consent: vendor2AndPurpose2Consent, + expectedAllowSync: false, + expectedAllowBidReq: false, + expectedPassID: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + perms := permissionsImpl{ + cfg: &tcf2AggConfig, + hostVendorID: 2, + vendorIDs: map[openrtb_ext.BidderName]uint16{ + openrtb_ext.BidderAppnexus: 2, + }, + fetchVendorList: listFetcher(map[uint16]map[uint16]vendorlist.VendorList{ + 2: { + 1: parseVendorListDataV2(t, vendorListData), + }, + }), + purposeEnforcerBuilder: NewPurposeEnforcerBuilder(&tcf2AggConfig), + nonStandardPublishers: map[string]struct{}{}, + gdprSignal: SignalYes, + consent: tt.consent, + validGVLVendorIDs: tt.validGVLVendorIDs, + } + + allowSync, err := perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderAppnexus) + assert.NoError(t, err) + assert.Equal(t, tt.expectedAllowSync, allowSync, "BidderSyncAllowed") + + auctionPerms := perms.AuctionActivitiesAllowed(context.Background(), openrtb_ext.BidderAppnexus, openrtb_ext.BidderAppnexus) + assert.Equal(t, tt.expectedAllowBidReq, auctionPerms.AllowBidRequest, "AllowBidRequest") + assert.Equal(t, tt.expectedPassID, auctionPerms.PassID, "PassID") + }) + } +} + func TestVendorListSelection(t *testing.T) { policyVersion3WithVendor2AndPurpose1Consent := "CPGWbY_PGWbY_GYAAAENABDAAIAAAAAAAAAAACEAAAAA" policyVersion4WithVendor2AndPurpose1Consent := "CPGWbY_PGWbY_GYAAAENABEAAIAAAAAAAAAAACEAAAAA" diff --git a/gdpr/purpose_config.go b/gdpr/purpose_config.go index 020d0aaa06..9838c873f1 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/v3/config" + "github.com/prebid/prebid-server/v4/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 61b7b9b2d6..025019ea0b 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/purpose_enforcer.go b/gdpr/purpose_enforcer.go index 5cc5d8e83d..28a0c6dcd1 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/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/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 756bb07d71..a73f6b3ee8 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/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/signal.go b/gdpr/signal.go index 478985b64f..b8bb49c27f 100644 --- a/gdpr/signal.go +++ b/gdpr/signal.go @@ -3,7 +3,7 @@ package gdpr import ( "strconv" - "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v4/errortypes" ) type Signal int diff --git a/gdpr/utils.go b/gdpr/utils.go index 543b70a4b5..a8efc30872 100644 --- a/gdpr/utils.go +++ b/gdpr/utils.go @@ -7,8 +7,8 @@ import ( gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" - "github.com/prebid/prebid-server/v3/openrtb_ext" - gppPolicy "github.com/prebid/prebid-server/v3/privacy/gpp" + "github.com/prebid/prebid-server/v4/openrtb_ext" + gppPolicy "github.com/prebid/prebid-server/v4/privacy/gpp" ) // GetGDPR will pull the gdpr flag from an openrtb request diff --git a/gdpr/utils_test.go b/gdpr/utils_test.go index 01fae95de3..747b550db3 100644 --- a/gdpr/utils_test.go +++ b/gdpr/utils_test.go @@ -6,8 +6,8 @@ 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/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/vendorlist-fetching.go b/gdpr/vendorlist-fetching.go index 2a3be433ec..4632c5d6b0 100644 --- a/gdpr/vendorlist-fetching.go +++ b/gdpr/vendorlist-fetching.go @@ -13,15 +13,19 @@ import ( "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/vendorlist" "github.com/prebid/go-gdpr/vendorlist2" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" "golang.org/x/net/context/ctxhttp" ) type saveVendors func(uint16, uint16, api.VendorList) type VendorListFetcher func(ctx context.Context, specVersion uint16, listVersion uint16, metricsEngine metrics.MetricsEngine) (vendorlist.VendorList, error) +// latestSpecVersion is the highest GVL specification version supported. Update this value when +// a new spec version is introduced by the IAB. +const latestSpecVersion = 3 + // This file provides the vendorlist-fetching function for Prebid Server. // // For more info, see https://github.com/prebid/prebid-server/issues/504 @@ -72,7 +76,7 @@ func preloadCache(ctx context.Context, client *http.Client, urlMaker func(uint16 firstListVersion: 2, // The GVL for TCF2 has no vendors defined in its first version. It's very unlikely to be used, so don't preload it. }, { - specVersion: 3, + specVersion: latestSpecVersion, firstListVersion: 1, }, } diff --git a/gdpr/vendorlist-fetching_test.go b/gdpr/vendorlist-fetching_test.go index 4ba228244b..8a587bd7f2 100644 --- a/gdpr/vendorlist-fetching_test.go +++ b/gdpr/vendorlist-fetching_test.go @@ -11,9 +11,9 @@ import ( "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/metrics" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) func TestFetcherDynamicLoadListExists(t *testing.T) { diff --git a/go.mod b/go.mod index 086f2525a5..06de764a5b 100644 --- a/go.mod +++ b/go.mod @@ -1,25 +1,24 @@ -module github.com/prebid/prebid-server/v3 +module github.com/prebid/prebid-server/v4 -go 1.23.0 - -retract v3.0.0 // Forgot to update major version in import path and module name +go 1.25.0 require ( github.com/51Degrees/device-detection-go/v4 v4.4.35 github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/IABTechLab/adscert v0.34.0 github.com/NYTimes/gziphandler v1.1.1 + github.com/WURFL/golang-wurfl v1.30.3 github.com/alitto/pond v1.8.3 github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d github.com/benbjohnson/clock v1.3.0 - github.com/buger/jsonparser v1.1.1 + github.com/buger/jsonparser v1.1.2 github.com/chasex/glog v0.0.0-20160217080310-c62392af379c github.com/coocood/freecache v1.2.1 github.com/docker/go-units v0.4.0 github.com/go-sql-driver/mysql v1.6.0 github.com/gofrs/uuid v4.2.0+incompatible - github.com/golang/glog v1.2.4 - github.com/google/go-cmp v0.6.0 + github.com/golang/glog v1.2.5 + github.com/google/go-cmp v0.7.0 github.com/grafana/pyroscope-go/godeltaprof v0.1.9 github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 @@ -42,19 +41,19 @@ require ( github.com/vrischmann/go-metrics-influxdb v0.1.1 github.com/xeipuuv/gojsonschema v1.2.0 github.com/yudai/gojsondiff v1.0.0 - golang.org/x/net v0.38.0 - golang.org/x/text v0.23.0 - google.golang.org/grpc v1.56.3 + golang.org/x/net v0.55.0 + golang.org/x/text v0.37.0 + google.golang.org/grpc v1.79.3 gopkg.in/evanphx/json-patch.v5 v5.9.0 gopkg.in/yaml.v3 v3.0.1 ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d // indirect github.com/klauspost/compress v1.17.8 // indirect @@ -80,10 +79,10 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect github.com/yudai/pp v2.0.1+incompatible // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/sys v0.31.0 // indirect + golang.org/x/crypto v0.52.0 // indirect + golang.org/x/sys v0.45.0 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/protobuf v1.36.10 // indirect gopkg.in/ini.v1 v1.66.4 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index de7723b629..2d975520cc 100644 --- a/go.sum +++ b/go.sum @@ -61,6 +61,8 @@ github.com/IABTechLab/adscert v0.34.0/go.mod h1:pCLd3Up1kfTrH6kYFUGGeavxIc1f6Tvv github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/WURFL/golang-wurfl v1.30.3 h1:a/ZR+/mwMrA9cEVa88ig47zkVJNl3HM5OTCpPvoSYmE= +github.com/WURFL/golang-wurfl v1.30.3/go.mod h1:cKXIyA0oIrbZ7YTOhBPX29ELt6XAM1/S7qyFIrTKkS0= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -84,15 +86,16 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk= +github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chasex/glog v0.0.0-20160217080310-c62392af379c h1:eXqCBUHfmjbeDqcuvzjsd+bM6A+bnwo5N9FVbV6m5/s= github.com/chasex/glog v0.0.0-20160217080310-c62392af379c/go.mod h1:omJZNg0Qu76bxJd+ExohVo8uXzNcGOk2bv7vel460xk= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -154,6 +157,10 @@ github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -165,8 +172,8 @@ github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= -github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= +github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -197,8 +204,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -216,8 +223,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -241,6 +248,8 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLe github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/tink/go v1.6.1/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -533,6 +542,18 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -551,8 +572,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= +golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -637,8 +658,8 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -749,8 +770,8 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -763,8 +784,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -828,6 +849,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -967,8 +990,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= -google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -983,8 +1006,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/hooks/empty_plan.go b/hooks/empty_plan.go index ea86a31405..a26bf8feb4 100644 --- a/hooks/empty_plan.go +++ b/hooks/empty_plan.go @@ -1,8 +1,8 @@ package hooks import ( - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks/hookstage" ) // EmptyPlanBuilder implements the ExecutionPlanBuilder interface diff --git a/hooks/hookanalytics/analytics_test.go b/hooks/hookanalytics/analytics_test.go index a1186e1b86..3f783d4b27 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/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/hooks/hookexecution/context.go b/hooks/hookexecution/context.go index 75ad2a8217..d0d8073dda 100644 --- a/hooks/hookexecution/context.go +++ b/hooks/hookexecution/context.go @@ -3,10 +3,10 @@ package hookexecution import ( "sync" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/privacy" ) // executionContext holds information passed to module's hook during hook execution. @@ -43,24 +43,27 @@ func (ctx executionContext) getModuleContext(moduleName string) hookstage.Module // moduleContexts preserves data the module wants to pass to itself from earlier stages to later stages. type moduleContexts struct { sync.RWMutex - ctxs map[string]hookstage.ModuleContext // format: {"module_name": hookstage.ModuleContext} + ctxs map[string]*hookstage.ModuleContext // format: {"module_name": hookstage.ModuleContext} } -func (mc *moduleContexts) put(moduleName string, mCtx hookstage.ModuleContext) { +func (mc *moduleContexts) put(moduleName string, mCtx *hookstage.ModuleContext) { + if mc == nil { + return + } mc.Lock() defer mc.Unlock() - newCtx := mCtx - if existingCtx, ok := mc.ctxs[moduleName]; ok && existingCtx != nil { - for k, v := range mCtx { - existingCtx[k] = v - } - newCtx = existingCtx + existingCtx, ok := mc.ctxs[moduleName] + if !ok { + mc.ctxs[moduleName] = mCtx + return } - mc.ctxs[moduleName] = newCtx + + // Add new data to existing context + existingCtx.SetAll(mCtx.GetAll()) } -func (mc *moduleContexts) get(moduleName string) (hookstage.ModuleContext, bool) { +func (mc *moduleContexts) get(moduleName string) (*hookstage.ModuleContext, bool) { mc.RLock() defer mc.RUnlock() mCtx, ok := mc.ctxs[moduleName] @@ -72,4 +75,4 @@ type stageModuleContext struct { groupCtx []groupModuleContext } -type groupModuleContext map[string]hookstage.ModuleContext +type groupModuleContext map[string]*hookstage.ModuleContext diff --git a/hooks/hookexecution/enricher.go b/hooks/hookexecution/enricher.go index 17a2eb9cc9..a7043a25a5 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/v3/config" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v5" ) diff --git a/hooks/hookexecution/enricher_test.go b/hooks/hookexecution/enricher_test.go index beb07444d1..d25b30b407 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/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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks/hookanalytics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 0e61ebc983..c8124d7c02 100644 --- a/hooks/hookexecution/errors.go +++ b/hooks/hookexecution/errors.go @@ -3,7 +3,7 @@ package hookexecution import ( "fmt" - "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v4/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 57a145dd1c..cb5b49c70c 100644 --- a/hooks/hookexecution/execution.go +++ b/hooks/hookexecution/execution.go @@ -8,15 +8,15 @@ import ( "sync" "time" - "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/logger" - "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" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/util/iputil" ) type hookResponse[T any] struct { diff --git a/hooks/hookexecution/execution_test.go b/hooks/hookexecution/execution_test.go index 1090db578d..5c3dd72943 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/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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/privacy" "github.com/stretchr/testify/assert" ) diff --git a/hooks/hookexecution/executor.go b/hooks/hookexecution/executor.go index 0e5b28fff8..eb66caf64a 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/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" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/privacy" ) const ( @@ -68,7 +68,7 @@ func NewHookExecutor(builder hooks.ExecutionPlanBuilder, endpoint string, me met endpoint: endpoint, planBuilder: builder, stageOutcomes: []StageOutcome{}, - moduleContexts: &moduleContexts{ctxs: make(map[string]hookstage.ModuleContext)}, + moduleContexts: &moduleContexts{ctxs: make(map[string]*hookstage.ModuleContext)}, metricEngine: me, } } diff --git a/hooks/hookexecution/executor_test.go b/hooks/hookexecution/executor_test.go index 4ce9933c83..3dd0e76c02 100644 --- a/hooks/hookexecution/executor_test.go +++ b/hooks/hookexecution/executor_test.go @@ -10,17 +10,17 @@ import ( "time" "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/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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/hooks/hookanalytics" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/metrics" + metricsConfig "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/privacy" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -61,7 +61,7 @@ func TestExecuteEntrypointStage(t *testing.T) { const body string = `{"name": "John", "last_name": "Doe"}` const urlString string = "https://prebid.com/openrtb2/auction" - foobarModuleCtx := &moduleContexts{ctxs: map[string]hookstage.ModuleContext{"foobar": nil}} + foobarModuleCtx := &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{"foobar": nil}} testCases := []struct { description string @@ -84,7 +84,7 @@ func TestExecuteEntrypointStage(t *testing.T) { expectedHeader: http.Header{}, expectedQuery: url.Values{}, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{}}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{}}, expectedStageOutcomes: []StageOutcome{}, }, { @@ -299,9 +299,18 @@ func TestExecuteEntrypointStage(t *testing.T) { expectedHeader: http.Header{}, expectedQuery: url.Values{}, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": {"entrypoint-ctx-1": "some-ctx-1", "entrypoint-ctx-3": "some-ctx-3"}, - "module-2": {"entrypoint-ctx-2": "some-ctx-2"}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-1", "some-ctx-1") + mc.Set("entrypoint-ctx-3", "some-ctx-3") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-2", "some-ctx-2") + return mc + }(), }}, expectedStageOutcomes: []StageOutcome{ { @@ -418,7 +427,7 @@ func TestExecuteRawAuctionStage(t *testing.T) { const bodyUpdated string = `{"last_name": "Doe", "foo": "bar"}` const urlString string = "https://prebid.com/openrtb2/auction" - foobarModuleCtx := &moduleContexts{ctxs: map[string]hookstage.ModuleContext{"foobar": nil}} + foobarModuleCtx := &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{"foobar": nil}} testCases := []struct { description string @@ -437,7 +446,7 @@ func TestExecuteRawAuctionStage(t *testing.T) { givenPlanBuilder: hooks.EmptyPlanBuilder{}, expectedBody: body, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{}}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{}}, expectedStageOutcomes: []StageOutcome{}, }, { @@ -613,9 +622,18 @@ func TestExecuteRawAuctionStage(t *testing.T) { givenPlanBuilder: TestWithModuleContextsPlanBuilder{}, expectedBody: body, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": {"raw-auction-ctx-1": "some-ctx-1", "raw-auction-ctx-3": "some-ctx-3"}, - "module-2": {"raw-auction-ctx-2": "some-ctx-2"}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("raw-auction-ctx-1", "some-ctx-1") + mc.Set("raw-auction-ctx-3", "some-ctx-3") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("raw-auction-ctx-2", "some-ctx-2") + return mc + }(), }}, expectedStageOutcomes: []StageOutcome{ { @@ -691,7 +709,7 @@ func TestExecuteRawAuctionStage(t *testing.T) { } func TestExecuteProcessedAuctionStage(t *testing.T) { - foobarModuleCtx := &moduleContexts{ctxs: map[string]hookstage.ModuleContext{"foobar": nil}} + foobarModuleCtx := &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{"foobar": nil}} req := openrtb2.BidRequest{ID: "some-id", User: &openrtb2.User{ID: "user-id"}} reqUpdated := openrtb2.BidRequest{ID: "some-id", User: &openrtb2.User{ID: "user-id", Yob: 2000, Consent: "true"}} @@ -710,7 +728,7 @@ func TestExecuteProcessedAuctionStage(t *testing.T) { givenRequest: openrtb_ext.RequestWrapper{BidRequest: &req}, expectedRequest: req, expectedErr: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{}}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{}}, expectedStageOutcomes: []StageOutcome{}, }, { @@ -831,9 +849,18 @@ func TestExecuteProcessedAuctionStage(t *testing.T) { givenRequest: openrtb_ext.RequestWrapper{BidRequest: &req}, expectedRequest: req, expectedErr: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": {"processed-auction-ctx-1": "some-ctx-1", "processed-auction-ctx-3": "some-ctx-3"}, - "module-2": {"processed-auction-ctx-2": "some-ctx-2"}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("processed-auction-ctx-1", "some-ctx-1") + mc.Set("processed-auction-ctx-3", "some-ctx-3") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("processed-auction-ctx-2", "some-ctx-2") + return mc + }(), }}, expectedStageOutcomes: []StageOutcome{ { @@ -910,7 +937,7 @@ func TestExecuteProcessedAuctionStage(t *testing.T) { func TestExecuteBidderRequestStage(t *testing.T) { bidderName := "the-bidder" - foobarModuleCtx := &moduleContexts{ctxs: map[string]hookstage.ModuleContext{"foobar": nil}} + foobarModuleCtx := &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{"foobar": nil}} expectedBidderRequest := &openrtb2.BidRequest{ID: "some-id", User: &openrtb2.User{ID: "user-id"}} expectedUpdatedBidderRequest := &openrtb2.BidRequest{ @@ -938,7 +965,7 @@ func TestExecuteBidderRequestStage(t *testing.T) { givenPlanBuilder: hooks.EmptyPlanBuilder{}, expectedBidderRequest: expectedBidderRequest, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{}}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{}}, expectedStageOutcomes: []StageOutcome{}, }, { @@ -1106,9 +1133,17 @@ func TestExecuteBidderRequestStage(t *testing.T) { givenPlanBuilder: TestWithModuleContextsPlanBuilder{}, expectedBidderRequest: expectedBidderRequest, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": {"bidder-request-ctx-1": "some-ctx-1"}, - "module-2": {"bidder-request-ctx-2": "some-ctx-2"}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("bidder-request-ctx-1", "some-ctx-1") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("bidder-request-ctx-2", "some-ctx-2") + return mc + }(), }}, expectedStageOutcomes: []StageOutcome{ { @@ -1218,7 +1253,7 @@ func buildDefaultActivityConfig(componentName string, allow bool) config.Activit } func TestExecuteRawBidderResponseStage(t *testing.T) { - foobarModuleCtx := &moduleContexts{ctxs: map[string]hookstage.ModuleContext{"foobar": nil}} + foobarModuleCtx := &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{"foobar": nil}} resp := adapters.BidderResponse{Bids: []*adapters.TypedBid{{DealPriority: 1}}} expResp := adapters.BidderResponse{Bids: []*adapters.TypedBid{{DealPriority: 10}}} vEntity := entity("the-bidder") @@ -1238,7 +1273,7 @@ func TestExecuteRawBidderResponseStage(t *testing.T) { givenBidderResponse: resp, expectedBidderResponse: resp, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{}}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{}}, expectedStageOutcomes: []StageOutcome{}, }, { @@ -1357,9 +1392,18 @@ func TestExecuteRawBidderResponseStage(t *testing.T) { givenBidderResponse: resp, expectedBidderResponse: expResp, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": {"raw-bidder-response-ctx-1": "some-ctx-1", "raw-bidder-response-ctx-3": "some-ctx-3"}, - "module-2": {"raw-bidder-response-ctx-2": "some-ctx-2"}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("raw-bidder-response-ctx-1", "some-ctx-1") + mc.Set("raw-bidder-response-ctx-3", "some-ctx-3") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("raw-bidder-response-ctx-2", "some-ctx-2") + return mc + }(), }}, expectedStageOutcomes: []StageOutcome{ { @@ -1435,7 +1479,7 @@ func TestExecuteRawBidderResponseStage(t *testing.T) { } func TestExecuteAllProcessedBidResponsesStage(t *testing.T) { - foobarModuleCtx := &moduleContexts{ctxs: map[string]hookstage.ModuleContext{"foobar": nil}} + foobarModuleCtx := &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{"foobar": nil}} expectedAllProcBidResponses := map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{ "some-bidder": {Bids: []*entities.PbsOrtbBid{{DealPriority: 1}}}, @@ -1461,7 +1505,7 @@ func TestExecuteAllProcessedBidResponsesStage(t *testing.T) { givenPlanBuilder: hooks.EmptyPlanBuilder{}, expectedBiddersResponse: expectedAllProcBidResponses, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{}}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{}}, expectedStageOutcomes: []StageOutcome{}, }, { @@ -1642,9 +1686,17 @@ func TestExecuteAllProcessedBidResponsesStage(t *testing.T) { givenPlanBuilder: TestWithModuleContextsPlanBuilder{}, expectedBiddersResponse: expectedAllProcBidResponses, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": {"all-processed-bid-responses-ctx-1": "some-ctx-1"}, - "module-2": {"all-processed-bid-responses-ctx-2": "some-ctx-2"}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("all-processed-bid-responses-ctx-1", "some-ctx-1") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("all-processed-bid-responses-ctx-2", "some-ctx-2") + return mc + }(), }}, expectedStageOutcomes: []StageOutcome{ { @@ -1709,7 +1761,7 @@ func TestExecuteAllProcessedBidResponsesStage(t *testing.T) { } func TestExecuteAuctionResponseStage(t *testing.T) { - foobarModuleCtx := &moduleContexts{ctxs: map[string]hookstage.ModuleContext{"foobar": nil}} + foobarModuleCtx := &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{"foobar": nil}} resp := &openrtb2.BidResponse{CustomData: "some-custom-data"} expResp := &openrtb2.BidResponse{CustomData: "new-custom-data"} @@ -1728,7 +1780,7 @@ func TestExecuteAuctionResponseStage(t *testing.T) { givenResponse: resp, expectedResponse: resp, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{}}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{}}, expectedStageOutcomes: []StageOutcome{}, }, { @@ -1877,9 +1929,18 @@ func TestExecuteAuctionResponseStage(t *testing.T) { givenResponse: resp, expectedResponse: resp, expectedReject: nil, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": {"auction-response-ctx-1": "some-ctx-1", "auction-response-ctx-3": "some-ctx-3"}, - "module-2": {"auction-response-ctx-2": "some-ctx-2"}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("auction-response-ctx-1", "some-ctx-1") + mc.Set("auction-response-ctx-3", "some-ctx-3") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("auction-response-ctx-2", "some-ctx-2") + return mc + }(), }}, expectedStageOutcomes: []StageOutcome{ { @@ -2000,7 +2061,7 @@ func TestExecuteExitpointStage(t *testing.T) { expectedResponseHeaders: http.Header{ "Content-Type": []string{"application/json"}, }, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{}}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{}}, expectedStageOutcomes: []StageOutcome{}, }, { @@ -2027,7 +2088,7 @@ func TestExecuteExitpointStage(t *testing.T) { expectedResponseHeaders: http.Header{ "Content-Type": []string{"application/xml"}, }, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{"foobar": nil}}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{"foobar": nil}}, expectedStageOutcomes: []StageOutcome{ { Entity: "exitpoint", @@ -2068,7 +2129,7 @@ func TestExecuteExitpointStage(t *testing.T) { }, expectedResponse: ``, expectedResponseHeaders: http.Header{"Content-Type": []string{"application/xml"}}, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{"foobar": nil}}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{"foobar": nil}}, expectedStageOutcomes: []StageOutcome{ { Entity: entityExitpoint, @@ -2144,7 +2205,7 @@ func TestExecuteExitpointStage(t *testing.T) { }, expectedResponse: ``, expectedResponseHeaders: http.Header{"Content-Type": []string{"application/xml"}}, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{"foobar": nil}}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{"foobar": nil}}, expectedStageOutcomes: []StageOutcome{ { Entity: entityExitpoint, @@ -2202,9 +2263,18 @@ func TestExecuteExitpointStage(t *testing.T) { }, expectedResponse: &openrtb2.BidResponse{ID: "test-id"}, expectedResponseHeaders: http.Header{"Content-Type": []string{"application/json"}}, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": {"exitpoint-ctx-1": "some-ctx-1", "exitpoint-ctx-3": "some-ctx-3"}, - "module-2": {"exitpoint-ctx-2": "some-ctx-2"}, + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("exitpoint-ctx-1", "some-ctx-1") + mc.Set("exitpoint-ctx-3", "some-ctx-3") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("exitpoint-ctx-2", "some-ctx-2") + return mc + }(), }}, expectedStageOutcomes: []StageOutcome{ { @@ -2277,7 +2347,7 @@ func TestExecuteExitpointStage(t *testing.T) { expectedResponseHeaders: http.Header{ "Content-Type": []string{"application/json"}, }, - expectedModuleContexts: &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ + expectedModuleContexts: &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ "module-1": nil, "module-2": nil, }}, @@ -2345,12 +2415,18 @@ func TestInterStageContextCommunication(t *testing.T) { assert.Nil(t, reject, "Unexpected reject from entrypoint stage.") assert.Equal( t, - &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": { - "entrypoint-ctx-1": "some-ctx-1", - "entrypoint-ctx-3": "some-ctx-3", - }, - "module-2": {"entrypoint-ctx-2": "some-ctx-2"}, + &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-1", "some-ctx-1") + mc.Set("entrypoint-ctx-3", "some-ctx-3") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-2", "some-ctx-2") + return mc + }(), }}, exec.moduleContexts, "Wrong module contexts after executing entrypoint hook.", @@ -2359,83 +2435,99 @@ func TestInterStageContextCommunication(t *testing.T) { // test that context added at the raw-auction stage merged with existing module contexts _, reject = exec.ExecuteRawAuctionStage(body) assert.Nil(t, reject, "Unexpected reject from raw-auction stage.") - assert.Equal(t, &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": { - "entrypoint-ctx-1": "some-ctx-1", - "entrypoint-ctx-3": "some-ctx-3", - "raw-auction-ctx-1": "some-ctx-1", - "raw-auction-ctx-3": "some-ctx-3", - }, - "module-2": { - "entrypoint-ctx-2": "some-ctx-2", - "raw-auction-ctx-2": "some-ctx-2", - }, + assert.Equal(t, &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-1", "some-ctx-1") + mc.Set("entrypoint-ctx-3", "some-ctx-3") + mc.Set("raw-auction-ctx-1", "some-ctx-1") + mc.Set("raw-auction-ctx-3", "some-ctx-3") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-2", "some-ctx-2") + mc.Set("raw-auction-ctx-2", "some-ctx-2") + return mc + }(), }}, exec.moduleContexts, "Wrong module contexts after executing raw-auction hook.") // test that context added at the processed-auction stage merged with existing module contexts err = exec.ExecuteProcessedAuctionStage(&openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{}}) assert.Nil(t, err, "Unexpected reject from processed-auction stage.") - assert.Equal(t, &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": { - "entrypoint-ctx-1": "some-ctx-1", - "entrypoint-ctx-3": "some-ctx-3", - "raw-auction-ctx-1": "some-ctx-1", - "raw-auction-ctx-3": "some-ctx-3", - "processed-auction-ctx-1": "some-ctx-1", - "processed-auction-ctx-3": "some-ctx-3", - }, - "module-2": { - "entrypoint-ctx-2": "some-ctx-2", - "raw-auction-ctx-2": "some-ctx-2", - "processed-auction-ctx-2": "some-ctx-2", - }, + assert.Equal(t, &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-1", "some-ctx-1") + mc.Set("entrypoint-ctx-3", "some-ctx-3") + mc.Set("raw-auction-ctx-1", "some-ctx-1") + mc.Set("raw-auction-ctx-3", "some-ctx-3") + mc.Set("processed-auction-ctx-1", "some-ctx-1") + mc.Set("processed-auction-ctx-3", "some-ctx-3") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-2", "some-ctx-2") + mc.Set("raw-auction-ctx-2", "some-ctx-2") + mc.Set("processed-auction-ctx-2", "some-ctx-2") + return mc + }(), }}, exec.moduleContexts, "Wrong module contexts after executing processed-auction hook.") // test that context added at the raw bidder response stage merged with existing module contexts reject = exec.ExecuteRawBidderResponseStage(&adapters.BidderResponse{}, "some-bidder") assert.Nil(t, reject, "Unexpected reject from raw-bidder-response stage.") - assert.Equal(t, &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": { - "entrypoint-ctx-1": "some-ctx-1", - "entrypoint-ctx-3": "some-ctx-3", - "raw-auction-ctx-1": "some-ctx-1", - "raw-auction-ctx-3": "some-ctx-3", - "processed-auction-ctx-1": "some-ctx-1", - "processed-auction-ctx-3": "some-ctx-3", - "raw-bidder-response-ctx-1": "some-ctx-1", - "raw-bidder-response-ctx-3": "some-ctx-3", - }, - "module-2": { - "entrypoint-ctx-2": "some-ctx-2", - "raw-auction-ctx-2": "some-ctx-2", - "processed-auction-ctx-2": "some-ctx-2", - "raw-bidder-response-ctx-2": "some-ctx-2", - }, + assert.Equal(t, &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-1", "some-ctx-1") + mc.Set("entrypoint-ctx-3", "some-ctx-3") + mc.Set("raw-auction-ctx-1", "some-ctx-1") + mc.Set("raw-auction-ctx-3", "some-ctx-3") + mc.Set("processed-auction-ctx-1", "some-ctx-1") + mc.Set("processed-auction-ctx-3", "some-ctx-3") + mc.Set("raw-bidder-response-ctx-1", "some-ctx-1") + mc.Set("raw-bidder-response-ctx-3", "some-ctx-3") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-2", "some-ctx-2") + mc.Set("raw-auction-ctx-2", "some-ctx-2") + mc.Set("processed-auction-ctx-2", "some-ctx-2") + mc.Set("raw-bidder-response-ctx-2", "some-ctx-2") + return mc + }(), }}, exec.moduleContexts, "Wrong module contexts after executing raw-bidder-response hook.") // test that context added at the auction-response stage merged with existing module contexts exec.ExecuteAuctionResponseStage(&openrtb2.BidResponse{}) assert.Nil(t, reject, "Unexpected reject from raw-auction stage.") - assert.Equal(t, &moduleContexts{ctxs: map[string]hookstage.ModuleContext{ - "module-1": { - "entrypoint-ctx-1": "some-ctx-1", - "entrypoint-ctx-3": "some-ctx-3", - "raw-auction-ctx-1": "some-ctx-1", - "raw-auction-ctx-3": "some-ctx-3", - "processed-auction-ctx-1": "some-ctx-1", - "processed-auction-ctx-3": "some-ctx-3", - "raw-bidder-response-ctx-1": "some-ctx-1", - "raw-bidder-response-ctx-3": "some-ctx-3", - "auction-response-ctx-1": "some-ctx-1", - "auction-response-ctx-3": "some-ctx-3", - }, - "module-2": { - "entrypoint-ctx-2": "some-ctx-2", - "raw-auction-ctx-2": "some-ctx-2", - "processed-auction-ctx-2": "some-ctx-2", - "raw-bidder-response-ctx-2": "some-ctx-2", - "auction-response-ctx-2": "some-ctx-2", - }, + assert.Equal(t, &moduleContexts{ctxs: map[string]*hookstage.ModuleContext{ + "module-1": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-1", "some-ctx-1") + mc.Set("entrypoint-ctx-3", "some-ctx-3") + mc.Set("raw-auction-ctx-1", "some-ctx-1") + mc.Set("raw-auction-ctx-3", "some-ctx-3") + mc.Set("processed-auction-ctx-1", "some-ctx-1") + mc.Set("processed-auction-ctx-3", "some-ctx-3") + mc.Set("raw-bidder-response-ctx-1", "some-ctx-1") + mc.Set("raw-bidder-response-ctx-3", "some-ctx-3") + mc.Set("auction-response-ctx-1", "some-ctx-1") + mc.Set("auction-response-ctx-3", "some-ctx-3") + return mc + }(), + "module-2": func() *hookstage.ModuleContext { + mc := hookstage.NewModuleContext() + mc.Set("entrypoint-ctx-2", "some-ctx-2") + mc.Set("raw-auction-ctx-2", "some-ctx-2") + mc.Set("processed-auction-ctx-2", "some-ctx-2") + mc.Set("raw-bidder-response-ctx-2", "some-ctx-2") + mc.Set("auction-response-ctx-2", "some-ctx-2") + return mc + }(), }}, exec.moduleContexts, "Wrong module contexts after executing auction-response hook.") } diff --git a/hooks/hookexecution/mocks_test.go b/hooks/hookexecution/mocks_test.go index 3d9d982861..a5857157d5 100644 --- a/hooks/hookexecution/mocks_test.go +++ b/hooks/hookexecution/mocks_test.go @@ -6,9 +6,9 @@ import ( "time" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) type mockUpdateHeaderEntrypointHook struct{} @@ -201,42 +201,50 @@ type mockModuleContextHook struct { } func (e mockModuleContextHook) HandleEntrypointHook(_ context.Context, miCtx hookstage.ModuleInvocationContext, _ hookstage.EntrypointPayload) (hookstage.HookResult[hookstage.EntrypointPayload], error) { - miCtx.ModuleContext = map[string]interface{}{e.key: e.val} + miCtx.ModuleContext = hookstage.NewModuleContext() + miCtx.ModuleContext.Set(e.key, e.val) return hookstage.HookResult[hookstage.EntrypointPayload]{ModuleContext: miCtx.ModuleContext}, nil } func (e mockModuleContextHook) HandleRawAuctionHook(_ context.Context, miCtx hookstage.ModuleInvocationContext, _ hookstage.RawAuctionRequestPayload) (hookstage.HookResult[hookstage.RawAuctionRequestPayload], error) { - miCtx.ModuleContext = map[string]interface{}{e.key: e.val} + miCtx.ModuleContext = hookstage.NewModuleContext() + miCtx.ModuleContext.Set(e.key, e.val) return hookstage.HookResult[hookstage.RawAuctionRequestPayload]{ModuleContext: miCtx.ModuleContext}, nil } func (e mockModuleContextHook) HandleProcessedAuctionHook(_ context.Context, miCtx hookstage.ModuleInvocationContext, _ hookstage.ProcessedAuctionRequestPayload) (hookstage.HookResult[hookstage.ProcessedAuctionRequestPayload], error) { - miCtx.ModuleContext = map[string]interface{}{e.key: e.val} + miCtx.ModuleContext = hookstage.NewModuleContext() + miCtx.ModuleContext.Set(e.key, e.val) return hookstage.HookResult[hookstage.ProcessedAuctionRequestPayload]{ModuleContext: miCtx.ModuleContext}, nil } func (e mockModuleContextHook) HandleBidderRequestHook(_ context.Context, miCtx hookstage.ModuleInvocationContext, _ hookstage.BidderRequestPayload) (hookstage.HookResult[hookstage.BidderRequestPayload], error) { - miCtx.ModuleContext = map[string]interface{}{e.key: e.val} + miCtx.ModuleContext = hookstage.NewModuleContext() + miCtx.ModuleContext.Set(e.key, e.val) return hookstage.HookResult[hookstage.BidderRequestPayload]{ModuleContext: miCtx.ModuleContext}, nil } func (e mockModuleContextHook) HandleRawBidderResponseHook(_ context.Context, miCtx hookstage.ModuleInvocationContext, _ hookstage.RawBidderResponsePayload) (hookstage.HookResult[hookstage.RawBidderResponsePayload], error) { - miCtx.ModuleContext = map[string]interface{}{e.key: e.val} + miCtx.ModuleContext = hookstage.NewModuleContext() + miCtx.ModuleContext.Set(e.key, e.val) return hookstage.HookResult[hookstage.RawBidderResponsePayload]{ModuleContext: miCtx.ModuleContext}, nil } func (e mockModuleContextHook) HandleAllProcessedBidResponsesHook(_ context.Context, miCtx hookstage.ModuleInvocationContext, _ hookstage.AllProcessedBidResponsesPayload) (hookstage.HookResult[hookstage.AllProcessedBidResponsesPayload], error) { - miCtx.ModuleContext = map[string]interface{}{e.key: e.val} + miCtx.ModuleContext = hookstage.NewModuleContext() + miCtx.ModuleContext.Set(e.key, e.val) return hookstage.HookResult[hookstage.AllProcessedBidResponsesPayload]{ModuleContext: miCtx.ModuleContext}, nil } func (e mockModuleContextHook) HandleAuctionResponseHook(_ context.Context, miCtx hookstage.ModuleInvocationContext, _ hookstage.AuctionResponsePayload) (hookstage.HookResult[hookstage.AuctionResponsePayload], error) { - miCtx.ModuleContext = map[string]interface{}{e.key: e.val} + miCtx.ModuleContext = hookstage.NewModuleContext() + miCtx.ModuleContext.Set(e.key, e.val) return hookstage.HookResult[hookstage.AuctionResponsePayload]{ModuleContext: miCtx.ModuleContext}, nil } func (e mockModuleContextHook) HandleExitpointHook(_ context.Context, miCtx hookstage.ModuleInvocationContext, _ hookstage.ExitpointPayload) (hookstage.HookResult[hookstage.ExitpointPayload], error) { - miCtx.ModuleContext = map[string]interface{}{e.key: e.val} + miCtx.ModuleContext = hookstage.NewModuleContext() + miCtx.ModuleContext.Set(e.key, e.val) return hookstage.HookResult[hookstage.ExitpointPayload]{ModuleContext: miCtx.ModuleContext}, nil } diff --git a/hooks/hookexecution/outcome.go b/hooks/hookexecution/outcome.go index d17d3cd467..b9c2561328 100644 --- a/hooks/hookexecution/outcome.go +++ b/hooks/hookexecution/outcome.go @@ -3,7 +3,7 @@ package hookexecution import ( "time" - "github.com/prebid/prebid-server/v3/hooks/hookanalytics" + "github.com/prebid/prebid-server/v4/hooks/hookanalytics" ) // Status indicates the result of hook execution. diff --git a/hooks/hookexecution/test_utils.go b/hooks/hookexecution/test_utils.go index b26d4aae4b..cd4f4d16ff 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/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/hooks/hookstage/allprocessedbidresponses.go b/hooks/hookstage/allprocessedbidresponses.go index 6bfe0d8082..09b4860261 100644 --- a/hooks/hookstage/allprocessedbidresponses.go +++ b/hooks/hookstage/allprocessedbidresponses.go @@ -3,8 +3,8 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/v3/exchange/entities" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // AllProcessedBidResponses hooks are invoked over a list of all diff --git a/hooks/hookstage/bidderrequest.go b/hooks/hookstage/bidderrequest.go index 8c27f07242..ab06ad97a6 100644 --- a/hooks/hookstage/bidderrequest.go +++ b/hooks/hookstage/bidderrequest.go @@ -3,7 +3,7 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 3ab571ff8e..946f5b92c9 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/prebid/openrtb/v20/adcom1" ) diff --git a/hooks/hookstage/invocation.go b/hooks/hookstage/invocation.go index b5452af7fc..b0b1c00089 100644 --- a/hooks/hookstage/invocation.go +++ b/hooks/hookstage/invocation.go @@ -2,8 +2,10 @@ package hookstage import ( "encoding/json" + "maps" + "sync" - "github.com/prebid/prebid-server/v3/hooks/hookanalytics" + "github.com/prebid/prebid-server/v4/hooks/hookanalytics" ) // HookResult represents the result of execution the concrete hook instance. @@ -16,7 +18,7 @@ type HookResult[T any] struct { Warnings []string DebugMessages []string AnalyticsTags hookanalytics.Analytics - ModuleContext ModuleContext // holds values that the module wants to pass to itself at later stages + ModuleContext *ModuleContext // holds values that the module wants to pass to itself at later stages } // ModuleInvocationContext holds data passed to the module hook during invocation. @@ -28,11 +30,77 @@ type ModuleInvocationContext struct { // Endpoint represents the path of the current endpoint. Endpoint string // ModuleContext holds values that the module passes to itself from the previous stages. - ModuleContext ModuleContext + ModuleContext *ModuleContext // HookImplCode is the hook_impl_code for a module instance to differentiate between multiple hooks HookImplCode string } // ModuleContext holds arbitrary data passed between module hooks at different stages. // We use interface as we do not know exactly how the modules will use their inner context. -type ModuleContext map[string]interface{} +type ModuleContext struct { + sync.RWMutex + data map[string]any +} + +// NewModuleContext creates a new module context +func NewModuleContext() *ModuleContext { + moduleContext := ModuleContext{ + data: make(map[string]any), + } + return &moduleContext +} + +// Get retrieves a value from the module context with read lock +func (mc *ModuleContext) Get(key string) (any, bool) { + if mc == nil { + return nil, false + } + mc.RLock() + defer mc.RUnlock() + if mc.data == nil { + return nil, false + } + val, ok := mc.data[key] + return val, ok +} + +// Set stores a value in the module context with write lock +func (mc *ModuleContext) Set(key string, value any) { + if mc == nil { + return + } + mc.Lock() + defer mc.Unlock() + if mc.data == nil { + mc.data = make(map[string]any) + } + mc.data[key] = value +} + +// GetAll returns a copy of all data in the context +func (mc *ModuleContext) GetAll() map[string]any { + if mc == nil { + return nil + } + mc.RLock() + defer mc.RUnlock() + if mc.data == nil { + return nil + } + result := make(map[string]any, len(mc.data)) + maps.Copy(result, mc.data) + return result +} + +// SetAll merges the provided data into the module context +func (mc *ModuleContext) SetAll(data map[string]any) { + if mc == nil { + return + } + mc.Lock() + defer mc.Unlock() + if mc.data == nil { + mc.data = make(map[string]any, len(data)) + } + maps.Copy(mc.data, data) +} diff --git a/hooks/hookstage/processedauctionrequest.go b/hooks/hookstage/processedauctionrequest.go index 0674213882..deb2994ab5 100644 --- a/hooks/hookstage/processedauctionrequest.go +++ b/hooks/hookstage/processedauctionrequest.go @@ -3,7 +3,7 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // ProcessedAuctionRequest hooks are invoked after the request is parsed diff --git a/hooks/hookstage/processedauctionrequest_mutations.go b/hooks/hookstage/processedauctionrequest_mutations.go index 9cd9c64573..a98cbbc580 100644 --- a/hooks/hookstage/processedauctionrequest_mutations.go +++ b/hooks/hookstage/processedauctionrequest_mutations.go @@ -3,7 +3,7 @@ package hookstage import ( "encoding/json" "errors" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func (c *ChangeSet[T]) ProcessedAuctionRequest() ChangeSetProcessedAuctionRequest[T] { diff --git a/hooks/hookstage/processedauctionrequest_mutations_test.go b/hooks/hookstage/processedauctionrequest_mutations_test.go index bf7616a6d3..3bfb94bf0b 100644 --- a/hooks/hookstage/processedauctionrequest_mutations_test.go +++ b/hooks/hookstage/processedauctionrequest_mutations_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/hooks/hookstage/rawbidderresponse.go b/hooks/hookstage/rawbidderresponse.go index 52d1d8a1ba..9299a73600 100644 --- a/hooks/hookstage/rawbidderresponse.go +++ b/hooks/hookstage/rawbidderresponse.go @@ -3,7 +3,7 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v4/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 027598c651..203f9ac3bc 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/v3/adapters" + "github.com/prebid/prebid-server/v4/adapters" ) func (c *ChangeSet[T]) RawBidderResponse() ChangeSetRawBidderResponse[T] { diff --git a/hooks/plan.go b/hooks/plan.go index c64dfb1cfb..8324487d37 100644 --- a/hooks/plan.go +++ b/hooks/plan.go @@ -3,9 +3,9 @@ package hooks import ( "time" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/logger" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/logger" ) type Stage string diff --git a/hooks/plan_test.go b/hooks/plan_test.go index 3266d2177f..0d7639b583 100644 --- a/hooks/plan_test.go +++ b/hooks/plan_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/hooks/repo.go b/hooks/repo.go index e00077e7bc..e9e545b50b 100644 --- a/hooks/repo.go +++ b/hooks/repo.go @@ -3,7 +3,7 @@ package hooks import ( "fmt" - "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v4/hooks/hookstage" ) // HookRepository is the interface that exposes methods diff --git a/hooks/repo_test.go b/hooks/repo_test.go index d6d3713351..b31554d406 100644 --- a/hooks/repo_test.go +++ b/hooks/repo_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v4/hooks/hookstage" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/injector/injector.go b/injector/injector.go index 9de2c1b726..0df0c2aeaa 100644 --- a/injector/injector.go +++ b/injector/injector.go @@ -6,8 +6,8 @@ import ( "io" "strings" - "github.com/prebid/prebid-server/v3/macros" - "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/metrics" ) const ( diff --git a/injector/injector_test.go b/injector/injector_test.go index b3457b094b..4010066228 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/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/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/macros/macros.go b/macros/macros.go index 0c6e08cae0..2473be05e7 100644 --- a/macros/macros.go +++ b/macros/macros.go @@ -25,6 +25,10 @@ type EndpointTemplateParams struct { PartnerId string Region string PlacementID string + NetworkId string + SiteDomain string + AppDomain string + Bundle string } // UserSyncPrivacy specifies privacy policy macros, represented as strings, for user sync urls. diff --git a/macros/provider.go b/macros/provider.go index 575aa49aa5..fa9b584b4d 100644 --- a/macros/provider.go +++ b/macros/provider.go @@ -5,8 +5,8 @@ import ( "strconv" "time" - "github.com/prebid/prebid-server/v3/exchange/entities" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const ( diff --git a/macros/provider_test.go b/macros/provider_test.go index 795fae9c41..cc92b0dc78 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/v3/exchange/entities" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/macros/string_index_based_replacer_test.go b/macros/string_index_based_replacer_test.go index 515640d4ff..868592790f 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/v3/exchange/entities" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/exchange/entities" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/main.go b/main.go index 9964238878..8ab997468e 100644 --- a/main.go +++ b/main.go @@ -10,14 +10,14 @@ import ( "time" jsoniter "github.com/json-iterator/go" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/currency" - "github.com/prebid/prebid-server/v3/logger" - "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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/router" + "github.com/prebid/prebid-server/v4/server" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/task" "github.com/spf13/viper" ) diff --git a/main_test.go b/main_test.go index 494e6d6774..92c0b90200 100644 --- a/main_test.go +++ b/main_test.go @@ -4,7 +4,7 @@ import ( "os" "testing" - "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v4/config" "github.com/stretchr/testify/assert" "github.com/spf13/viper" diff --git a/metrics/config/metrics.go b/metrics/config/metrics.go index cb039155bf..6ef2d552c0 100644 --- a/metrics/config/metrics.go +++ b/metrics/config/metrics.go @@ -3,10 +3,10 @@ package config import ( "time" - "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" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + prometheusmetrics "github.com/prebid/prebid-server/v4/metrics/prometheus" + "github.com/prebid/prebid-server/v4/openrtb_ext" gometrics "github.com/rcrowley/go-metrics" influxdb "github.com/vrischmann/go-metrics-influxdb" ) @@ -299,6 +299,12 @@ func (me *MultiMetricsEngine) RecordGvlListRequest() { } } +func (me *MultiMetricsEngine) RecordLiveGVLFetch(success bool) { + for _, thisME := range *me { + thisME.RecordLiveGVLFetch(success) + } +} + func (me *MultiMetricsEngine) RecordAdsCertReq(success bool) { for _, thisME := range *me { thisME.RecordAdsCertReq(success) @@ -534,6 +540,9 @@ func (me *NilMetricsEngine) RecordStoredResponse(pubId string) { func (me *NilMetricsEngine) RecordGvlListRequest() { } +func (me *NilMetricsEngine) RecordLiveGVLFetch(success bool) { +} + func (me *NilMetricsEngine) RecordAdsCertReq(success bool) { } diff --git a/metrics/config/metrics_test.go b/metrics/config/metrics_test.go index 48166f07fc..1b35f59b1e 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/v3/config" - "github.com/prebid/prebid-server/v3/metrics" - "github.com/prebid/prebid-server/v3/openrtb_ext" + mainConfig "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" gometrics "github.com/rcrowley/go-metrics" ) diff --git a/metrics/go_metrics.go b/metrics/go_metrics.go index aa64e41a8d..4f10166c17 100644 --- a/metrics/go_metrics.go +++ b/metrics/go_metrics.go @@ -6,9 +6,9 @@ import ( "sync" "time" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/openrtb_ext" metrics "github.com/rcrowley/go-metrics" ) @@ -36,6 +36,8 @@ type Metrics struct { BidderServerResponseTimer metrics.Timer StoredResponsesMeter metrics.Meter GvlListRequestsMeter metrics.Meter + LiveGVLFetchSuccess metrics.Meter + LiveGVLFetchFailure metrics.Meter // Metrics for OpenRTB requests specifically RequestStatuses map[RequestType]map[RequestStatus]metrics.Meter @@ -188,6 +190,8 @@ func NewBlankMetrics(registry metrics.Registry, exchanges []string, disabledMetr SyncerSetsMeter: make(map[string]map[SyncerSetUidStatus]metrics.Meter), StoredResponsesMeter: blankMeter, GvlListRequestsMeter: blankMeter, + LiveGVLFetchSuccess: blankMeter, + LiveGVLFetchFailure: blankMeter, ImpsTypeBanner: blankMeter, ImpsTypeVideo: blankMeter, @@ -314,6 +318,8 @@ func NewMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderName, d newMetrics.PrebidCacheRequestTimerError = metrics.GetOrRegisterTimer("prebid_cache_request_time.err", registry) newMetrics.StoredResponsesMeter = metrics.GetOrRegisterMeter("stored_responses", registry) newMetrics.GvlListRequestsMeter = metrics.GetOrRegisterMeter("gvl_requests", registry) + newMetrics.LiveGVLFetchSuccess = metrics.GetOrRegisterMeter("live_gvl_fetch.ok", registry) + newMetrics.LiveGVLFetchFailure = metrics.GetOrRegisterMeter("live_gvl_fetch.failed", registry) newMetrics.OverheadTimer = makeOverheadTimerMetrics(registry) newMetrics.BidderServerResponseTimer = metrics.GetOrRegisterTimer("bidder_server_response_time_seconds", registry) @@ -658,6 +664,14 @@ func (me *Metrics) RecordGvlListRequest() { me.GvlListRequestsMeter.Mark(1) } +func (me *Metrics) RecordLiveGVLFetch(success bool) { + if success { + me.LiveGVLFetchSuccess.Mark(1) + } else { + me.LiveGVLFetchFailure.Mark(1) + } +} + func (me *Metrics) RecordImps(labels ImpLabels) { me.ImpMeter.Mark(int64(1)) if labels.BannerImps { diff --git a/metrics/go_metrics_test.go b/metrics/go_metrics_test.go index 2fcec9cb6d..553dfba09d 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/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" metrics "github.com/rcrowley/go-metrics" "github.com/stretchr/testify/assert" ) @@ -37,6 +37,8 @@ func TestNewMetrics(t *testing.T) { ensureContains(t, registry, "setuid_requests.syncer_unknown", m.SetUidStatusMeter[SetUidSyncerUnknown]) ensureContains(t, registry, "stored_responses", m.StoredResponsesMeter) ensureContains(t, registry, "gvl_requests", m.GvlListRequestsMeter) + ensureContains(t, registry, "live_gvl_fetch.ok", m.LiveGVLFetchSuccess) + ensureContains(t, registry, "live_gvl_fetch.failed", m.LiveGVLFetchFailure) ensureContains(t, registry, "prebid_cache_request_time.ok", m.PrebidCacheRequestTimerSuccess) ensureContains(t, registry, "prebid_cache_request_time.err", m.PrebidCacheRequestTimerError) diff --git a/metrics/metrics.go b/metrics/metrics.go index 054bf8940a..aa2e28b7c8 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -3,7 +3,7 @@ package metrics import ( "time" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // Labels defines the labels that can be attached to the metrics. @@ -497,6 +497,7 @@ type MetricsEngine interface { RecordDebugRequest(debugEnabled bool, pubId string) RecordStoredResponse(pubId string) RecordGvlListRequest() + RecordLiveGVLFetch(success bool) RecordAdsCertReq(success bool) RecordAdsCertSignTime(adsCertSignTime time.Duration) RecordBidValidationCreativeSizeError(adapter openrtb_ext.BidderName, account string) diff --git a/metrics/metrics_mock.go b/metrics/metrics_mock.go index 09fa605166..7cf0af5cc0 100644 --- a/metrics/metrics_mock.go +++ b/metrics/metrics_mock.go @@ -3,7 +3,7 @@ package metrics import ( "time" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/mock" ) @@ -179,6 +179,10 @@ func (me *MetricsEngineMock) RecordGvlListRequest() { me.Called() } +func (me *MetricsEngineMock) RecordLiveGVLFetch(success bool) { + me.Called(success) +} + func (me *MetricsEngineMock) RecordAdsCertReq(success bool) { me.Called(success) } diff --git a/metrics/prometheus/preload.go b/metrics/prometheus/preload.go index 9753fcd025..d25540fb02 100644 --- a/metrics/prometheus/preload.go +++ b/metrics/prometheus/preload.go @@ -1,8 +1,8 @@ package prometheusmetrics import ( - "github.com/prebid/prebid-server/v3/metrics" - // "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/metrics" + // "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/prometheus/client_golang/prometheus" ) diff --git a/metrics/prometheus/prometheus.go b/metrics/prometheus/prometheus.go index 359e57a948..443184b31e 100644 --- a/metrics/prometheus/prometheus.go +++ b/metrics/prometheus/prometheus.go @@ -6,9 +6,9 @@ import ( "strings" "time" - "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/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/prometheus/client_golang/prometheus" promCollector "github.com/prometheus/client_golang/prometheus/collectors" ) @@ -55,6 +55,7 @@ type Metrics struct { privacyTCF *prometheus.CounterVec storedResponses prometheus.Counter gvlListRequests prometheus.Counter + liveGVLFetch *prometheus.CounterVec storedResponsesFetchTimer *prometheus.HistogramVec storedResponsesErrors *prometheus.CounterVec adsCertRequests *prometheus.CounterVec @@ -379,6 +380,11 @@ func NewMetrics(cfg config.PrometheusMetrics, disabledMetrics config.DisabledMet "gvl_requests", "Count number of times GVL list is fetched") + metrics.liveGVLFetch = newCounter(cfg, reg, + "live_gvl_fetch", + "Count of live GVL vendor ID fetches labeled by success or failure.", + []string{successLabel}) + metrics.adapterBids = newCounter(cfg, reg, "adapter_bids", "Count of bids labeled by adapter and markup delivery type (adm or nurl).", @@ -739,6 +745,18 @@ func (m *Metrics) RecordGvlListRequest() { m.gvlListRequests.Inc() } +func (m *Metrics) RecordLiveGVLFetch(success bool) { + if success { + m.liveGVLFetch.With(prometheus.Labels{ + successLabel: requestSuccessful, + }).Inc() + } else { + m.liveGVLFetch.With(prometheus.Labels{ + successLabel: requestFailed, + }).Inc() + } +} + func (m *Metrics) RecordImps(labels metrics.ImpLabels) { m.impressions.With(prometheus.Labels{ isBannerLabel: strconv.FormatBool(labels.BannerImps), diff --git a/metrics/prometheus/prometheus_test.go b/metrics/prometheus/prometheus_test.go index 8af11d79aa..7bf5b79af7 100644 --- a/metrics/prometheus/prometheus_test.go +++ b/metrics/prometheus/prometheus_test.go @@ -6,9 +6,9 @@ import ( "testing" "time" - "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/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" "github.com/stretchr/testify/assert" @@ -1952,6 +1952,26 @@ func TestRecordGvlListRequest(t *testing.T) { assertCounterValue(t, "Record instance of fetched GVL list", "success", m.gvlListRequests, 1.00) } +func TestRecordLiveGVLFetch(t *testing.T) { + m := createMetricsForTesting() + + m.RecordLiveGVLFetch(true) + m.RecordLiveGVLFetch(true) + m.RecordLiveGVLFetch(false) + + assertCounterVecValue(t, "", "live_gvl_fetch:ok", m.liveGVLFetch, + float64(2), + prometheus.Labels{ + successLabel: requestSuccessful, + }) + + assertCounterVecValue(t, "", "live_gvl_fetch:fail", m.liveGVLFetch, + float64(1), + prometheus.Labels{ + successLabel: requestFailed, + }) +} + func TestRecordAdsCertReqMetric(t *testing.T) { testCases := []struct { description string diff --git a/modules/builder.go b/modules/builder.go index 85a38fd022..df2f1b1c3a 100644 --- a/modules/builder.go +++ b/modules/builder.go @@ -1,10 +1,11 @@ package modules import ( - fiftyonedegreesDevicedetection "github.com/prebid/prebid-server/v3/modules/fiftyonedegrees/devicedetection" - prebidOrtb2blocking "github.com/prebid/prebid-server/v3/modules/prebid/ortb2blocking" - prebidRulesengine "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine" - scope3Rtd "github.com/prebid/prebid-server/v3/modules/scope3/rtd" + fiftyonedegreesDevicedetection "github.com/prebid/prebid-server/v4/modules/fiftyonedegrees/devicedetection" + prebidOrtb2blocking "github.com/prebid/prebid-server/v4/modules/prebid/ortb2blocking" + prebidRulesengine "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine" + wurflDevicedetection "github.com/prebid/prebid-server/v4/modules/scientiamobile/wurfl_devicedetection" + scope3Rtd "github.com/prebid/prebid-server/v4/modules/scope3/rtd" ) // builders returns mapping between module name and its builder @@ -18,6 +19,9 @@ func builders() ModuleBuilders { "ortb2blocking": prebidOrtb2blocking.Builder, "rulesengine": prebidRulesengine.Builder, }, + "scientiamobile": { + "wurfl_devicedetection": wurflDevicedetection.Builder, + }, "scope3": { "rtd": scope3Rtd.Builder, }, diff --git a/modules/fiftyonedegrees/devicedetection/config.go b/modules/fiftyonedegrees/devicedetection/config.go index 3a83030b6d..8037f83ec5 100644 --- a/modules/fiftyonedegrees/devicedetection/config.go +++ b/modules/fiftyonedegrees/devicedetection/config.go @@ -8,7 +8,7 @@ import ( "os" "github.com/51Degrees/device-detection-go/v4/dd" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type config struct { diff --git a/modules/fiftyonedegrees/devicedetection/device_detector.go b/modules/fiftyonedegrees/devicedetection/device_detector.go index 9f66c64eea..73c2f46601 100644 --- a/modules/fiftyonedegrees/devicedetection/device_detector.go +++ b/modules/fiftyonedegrees/devicedetection/device_detector.go @@ -68,6 +68,8 @@ func buildEngineOptions(moduleConfig *config, configHash *dd.ConfigHash) []onpre "HardwareModel", "HardwareFamily", "HardwareModelVariants", + "HardwareNamePrefix", + "HardwareNameVersion", "ScreenInchesHeight", "IsCrawler", }), diff --git a/modules/fiftyonedegrees/devicedetection/device_info_extractor.go b/modules/fiftyonedegrees/devicedetection/device_info_extractor.go index d16ac64f07..ef3aeef360 100644 --- a/modules/fiftyonedegrees/devicedetection/device_info_extractor.go +++ b/modules/fiftyonedegrees/devicedetection/device_info_extractor.go @@ -6,7 +6,7 @@ import ( "fmt" "strconv" - "github.com/prebid/prebid-server/v3/logger" + "github.com/prebid/prebid-server/v4/logger" ) // deviceInfoExtractor is a struct that contains the methods to extract device information @@ -44,6 +44,8 @@ const ( deviceInfoHardwareFamily deviceInfoProperty = "HardwareFamily" deviceInfoHardwareModelVariants deviceInfoProperty = "HardwareModelVariants" deviceInfoScreenInchesHeight deviceInfoProperty = "ScreenInchesHeight" + deviceInfoHardwareNamePrefix deviceInfoProperty = "HardwareNamePrefix" + deviceInfoHardwareNameVersion deviceInfoProperty = "HardwareNameVersion" ) func (x deviceInfoExtractor) extract(results Results, ua string) (*deviceInfo, error) { @@ -69,6 +71,8 @@ func (x deviceInfoExtractor) extract(results Results, ua string) (*deviceInfo, e hardwareFamily := x.getValue(results, deviceInfoHardwareFamily) hardwareModelVariants := x.getValue(results, deviceInfoHardwareModelVariants) screenInchedHeight, _ := strconv.ParseFloat(x.getValue(results, deviceInfoScreenInchesHeight), 10) + hardwareNamePrefix := x.getValue(results, deviceInfoHardwareNamePrefix) + hardwareNameVersion := x.getValue(results, deviceInfoHardwareNameVersion) p := &deviceInfo{ HardwareVendor: hardwareVendor, @@ -90,6 +94,8 @@ func (x deviceInfoExtractor) extract(results Results, ua string) (*deviceInfo, e HardwareModel: hardwareModel, HardwareFamily: hardwareFamily, HardwareModelVariants: hardwareModelVariants, + HardwareNamePrefix: hardwareNamePrefix, + HardwareNameVersion: hardwareNameVersion, ScreenInchesHeight: screenInchedHeight, } diff --git a/modules/fiftyonedegrees/devicedetection/device_info_extractor_test.go b/modules/fiftyonedegrees/devicedetection/device_info_extractor_test.go index 23bee8a5d5..481c93d45f 100644 --- a/modules/fiftyonedegrees/devicedetection/device_info_extractor_test.go +++ b/modules/fiftyonedegrees/devicedetection/device_info_extractor_test.go @@ -107,6 +107,8 @@ func mockValues(results *ResultsHashMock) { mockValue(results, "HardwareModel", "Macbook") mockValue(results, "HardwareFamily", "Macbook") mockValue(results, "HardwareModelVariants", "Macbook") + mockValue(results, "HardwareNamePrefix", "Macbook") + mockValue(results, "HardwareNameVersion", "Pro") mockValue(results, "ScreenInchesHeight", "12") } @@ -124,6 +126,8 @@ func assertDeviceInfo(t *testing.T, deviceInfo *deviceInfo) { assert.Equal(t, deviceInfo.PixelRatio, float64(223)) assert.Equal(t, deviceInfo.Javascript, true) assert.Equal(t, deviceInfo.GeoLocation, true) + assert.Equal(t, deviceInfo.HardwareNamePrefix, "Macbook") + assert.Equal(t, deviceInfo.HardwareNameVersion, "Pro") } func mockValue(results *ResultsHashMock, name string, value string) { diff --git a/modules/fiftyonedegrees/devicedetection/evidence_extractor.go b/modules/fiftyonedegrees/devicedetection/evidence_extractor.go index 700f53117d..9599e43de1 100644 --- a/modules/fiftyonedegrees/devicedetection/evidence_extractor.go +++ b/modules/fiftyonedegrees/devicedetection/evidence_extractor.go @@ -9,7 +9,7 @@ import ( "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/v4/hooks/hookstage" ) type defaultEvidenceExtractor struct { @@ -57,16 +57,18 @@ func merge(val1, val2 []stringEvidence) []stringEvidence { return evidence } -func (x *defaultEvidenceExtractor) extract(ctx hookstage.ModuleContext) ([]onpremise.Evidence, string, error) { +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]) + evidenceFromSuaCtx, _ := ctx.Get(evidenceFromSuaCtxKey) + suaStrings, err := x.getEvidenceStrings(evidenceFromSuaCtx) if err != nil { return nil, "", fmt.Errorf("error extracting sua evidence: %w", err) } - headerString, err := x.getEvidenceStrings(ctx[evidenceFromHeadersCtxKey]) + evidenceFromHeadersCtx, _ := ctx.Get(evidenceFromHeadersCtxKey) + headerString, err := x.getEvidenceStrings(evidenceFromHeadersCtx) if err != nil { return nil, "", fmt.Errorf("error extracting header evidence: %w", err) } diff --git a/modules/fiftyonedegrees/devicedetection/evidence_extractor_test.go b/modules/fiftyonedegrees/devicedetection/evidence_extractor_test.go index 7dc4fb9790..8c183af559 100644 --- a/modules/fiftyonedegrees/devicedetection/evidence_extractor_test.go +++ b/modules/fiftyonedegrees/devicedetection/evidence_extractor_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/51Degrees/device-detection-go/v4/dd" - "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v4/hooks/hookstage" "github.com/stretchr/testify/assert" ) @@ -129,7 +129,7 @@ func TestExtract(t *testing.T) { tests := []struct { name string - ctx hookstage.ModuleContext + ctx *hookstage.ModuleContext wantEvidenceCount int wantUserAgent string wantError bool @@ -141,96 +141,120 @@ func TestExtract(t *testing.T) { }, { name: "empty", - ctx: hookstage.ModuleContext{ - evidenceFromSuaCtxKey: []stringEvidence{}, - evidenceFromHeadersCtxKey: []stringEvidence{}, - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromHeadersCtxKey, []stringEvidence{}) + ctx.Set(evidenceFromSuaCtxKey, []stringEvidence{}) + return ctx + }(), wantEvidenceCount: 0, wantUserAgent: "", }, { name: "from_headers", - ctx: hookstage.ModuleContext{ - evidenceFromHeadersCtxKey: []stringEvidence{uaEvidence1}, - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromHeadersCtxKey, []stringEvidence{uaEvidence1}) + return ctx + }(), wantEvidenceCount: 1, wantUserAgent: "uav1", }, { name: "from_headers_no_user_agent", - ctx: hookstage.ModuleContext{ - evidenceFromHeadersCtxKey: []stringEvidence{evidence1}, - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromHeadersCtxKey, []stringEvidence{evidence1}) + return ctx + }(), wantError: true, }, { name: "from_sua", - ctx: hookstage.ModuleContext{ - evidenceFromSuaCtxKey: []stringEvidence{uaEvidence1}, - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromSuaCtxKey, []stringEvidence{uaEvidence1}) + return ctx + }(), wantEvidenceCount: 1, wantUserAgent: "uav1", }, { name: "from_sua_no_user_agent", - ctx: hookstage.ModuleContext{ - evidenceFromSuaCtxKey: []stringEvidence{evidence1}, - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromSuaCtxKey, []stringEvidence{evidence1}) + return ctx + }(), wantError: true, }, { name: "from_headers_error", - ctx: hookstage.ModuleContext{ - evidenceFromHeadersCtxKey: "bad value", - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromHeadersCtxKey, "bad value") + return ctx + }(), wantError: true, }, { name: "from_sua_error", - ctx: hookstage.ModuleContext{ - evidenceFromHeadersCtxKey: []stringEvidence{}, - evidenceFromSuaCtxKey: "bad value", - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromHeadersCtxKey, []stringEvidence{}) + ctx.Set(evidenceFromSuaCtxKey, "bad value") + return ctx + }(), wantError: true, }, { name: "from_sua_and_headers", - ctx: hookstage.ModuleContext{ - evidenceFromHeadersCtxKey: []stringEvidence{uaEvidence1}, - evidenceFromSuaCtxKey: []stringEvidence{evidence1}, - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromHeadersCtxKey, []stringEvidence{uaEvidence1}) + ctx.Set(evidenceFromSuaCtxKey, []stringEvidence{evidence1}) + return ctx + }(), wantEvidenceCount: 2, wantUserAgent: "uav1", }, { name: "from_sua_and_headers_sua_can_overwrite_if_ua_present", - ctx: hookstage.ModuleContext{ - evidenceFromHeadersCtxKey: []stringEvidence{uaEvidence1}, - evidenceFromSuaCtxKey: []stringEvidence{uaEvidence2}, - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromHeadersCtxKey, []stringEvidence{uaEvidence1}) + ctx.Set(evidenceFromSuaCtxKey, []stringEvidence{uaEvidence2}) + return ctx + }(), wantEvidenceCount: 1, wantUserAgent: "uav2", }, { name: "empty_string_values", - ctx: hookstage.ModuleContext{ - evidenceFromHeadersCtxKey: []stringEvidence{emptyEvidence}, - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromHeadersCtxKey, []stringEvidence{emptyEvidence}) + return ctx + }(), wantError: true, }, { name: "empty_sua_values", - ctx: hookstage.ModuleContext{ - evidenceFromSuaCtxKey: []stringEvidence{emptyEvidence}, - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromSuaCtxKey, []stringEvidence{emptyEvidence}) + return ctx + }(), wantError: true, }, { name: "mixed_valid_and_invalid", - ctx: hookstage.ModuleContext{ - evidenceFromHeadersCtxKey: []stringEvidence{uaEvidence1}, - evidenceFromSuaCtxKey: "bad value", - }, + ctx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(evidenceFromHeadersCtxKey, []stringEvidence{uaEvidence1}) + ctx.Set(evidenceFromSuaCtxKey, "bad value") + return ctx + }(), wantError: true, }, } diff --git a/modules/fiftyonedegrees/devicedetection/hook_auction_entrypoint.go b/modules/fiftyonedegrees/devicedetection/hook_auction_entrypoint.go index 8be51c422d..996845a2f0 100644 --- a/modules/fiftyonedegrees/devicedetection/hook_auction_entrypoint.go +++ b/modules/fiftyonedegrees/devicedetection/hook_auction_entrypoint.go @@ -3,8 +3,8 @@ package devicedetection import ( - "github.com/prebid/prebid-server/v3/hooks/hookexecution" - "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/hooks/hookstage" ) // handleAuctionEntryPointRequestHook is a hookstage.HookFunc that is used to handle the auction entrypoint request hook. @@ -18,10 +18,10 @@ func handleAuctionEntryPointRequestHook(cfg config, payload hookstage.Entrypoint 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 + moduleContext := hookstage.NewModuleContext() + moduleContext.Set(evidenceFromHeadersCtxKey, evidenceFromHeaders) + moduleContext.Set(evidenceFromSuaCtxKey, evidenceFromSua) + moduleContext.Set(ddEnabledCtxKey, true) return hookstage.HookResult[hookstage.EntrypointPayload]{ ModuleContext: moduleContext, diff --git a/modules/fiftyonedegrees/devicedetection/hook_raw_auction_request.go b/modules/fiftyonedegrees/devicedetection/hook_raw_auction_request.go index acde532eb5..1bf1aa8203 100644 --- a/modules/fiftyonedegrees/devicedetection/hook_raw_auction_request.go +++ b/modules/fiftyonedegrees/devicedetection/hook_raw_auction_request.go @@ -3,11 +3,10 @@ package devicedetection import ( - "fmt" "math" - "github.com/prebid/prebid-server/v3/hooks/hookexecution" - "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/hooks/hookstage" "github.com/tidwall/gjson" "github.com/tidwall/sjson" ) @@ -37,7 +36,7 @@ func handleAuctionRequestHook(ctx hookstage.ModuleInvocationContext, deviceDetec result, err := hydrateFields(deviceInfo, rawPayload) if err != nil { - return rawPayload, hookexecution.NewFailure(fmt.Sprintf("error hydrating fields %s", err)) + return rawPayload, hookexecution.NewFailure("error hydrating fields %s", err) } return result, nil @@ -117,6 +116,10 @@ func setMissingFields(deviceObj map[string]any, fiftyOneDd *deviceInfo) map[stri return val }, "model": func() any { + if fiftyOneDd.HardwareNamePrefix != "" && fiftyOneDd.HardwareNamePrefix != ddUnknown { + return fiftyOneDd.HardwareNamePrefix + } + // Fallback: HardwareModel → HardwareName newVal := fiftyOneDd.HardwareModel if newVal == ddUnknown { newVal = fiftyOneDd.HardwareName @@ -126,6 +129,12 @@ func setMissingFields(deviceObj map[string]any, fiftyOneDd *deviceInfo) map[stri } return nil }, + "hwv": func() any { + if fiftyOneDd.HardwareNameVersion != "" && fiftyOneDd.HardwareNameVersion != ddUnknown { + return fiftyOneDd.HardwareNameVersion + } + return nil + }, "ppi": func() any { if fiftyOneDd.ScreenPixelsHeight > 0 && fiftyOneDd.ScreenInchesHeight > 0 { ppi := float64(fiftyOneDd.ScreenPixelsHeight) / fiftyOneDd.ScreenInchesHeight diff --git a/modules/fiftyonedegrees/devicedetection/models.go b/modules/fiftyonedegrees/devicedetection/models.go index ffa9887235..6afb4ed038 100644 --- a/modules/fiftyonedegrees/devicedetection/models.go +++ b/modules/fiftyonedegrees/devicedetection/models.go @@ -62,6 +62,8 @@ type deviceInfo struct { HardwareFamily string HardwareModel string HardwareModelVariants string + HardwareNamePrefix string + HardwareNameVersion string UserAgent string DeviceId string ScreenInchesHeight float64 diff --git a/modules/fiftyonedegrees/devicedetection/module.go b/modules/fiftyonedegrees/devicedetection/module.go index 603f37810d..4dddc577f4 100644 --- a/modules/fiftyonedegrees/devicedetection/module.go +++ b/modules/fiftyonedegrees/devicedetection/module.go @@ -10,8 +10,8 @@ import ( "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/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/modules/moduledeps" ) func configHashFromConfig(cfg *config) *dd.ConfigHash { @@ -83,7 +83,7 @@ type accountValidator interface { type evidenceExtractor interface { fromHeaders(request *http.Request, httpHeaderKeys []dd.EvidenceKey) []stringEvidence fromSuaPayload(payload []byte) []stringEvidence - extract(ctx hookstage.ModuleContext) ([]onpremise.Evidence, string, error) + extract(ctx *hookstage.ModuleContext) ([]onpremise.Evidence, string, error) } func (m Module) HandleEntrypointHook( diff --git a/modules/fiftyonedegrees/devicedetection/module_no_cgo_test.go b/modules/fiftyonedegrees/devicedetection/module_no_cgo_test.go index 2f4bce4a99..9aca4faa09 100644 --- a/modules/fiftyonedegrees/devicedetection/module_no_cgo_test.go +++ b/modules/fiftyonedegrees/devicedetection/module_no_cgo_test.go @@ -5,7 +5,7 @@ package devicedetection import ( "testing" - "github.com/prebid/prebid-server/v3/modules/moduledeps" + "github.com/prebid/prebid-server/v4/modules/moduledeps" "github.com/stretchr/testify/assert" ) diff --git a/modules/fiftyonedegrees/devicedetection/module_test.go b/modules/fiftyonedegrees/devicedetection/module_test.go index 19595aca4e..32968515fc 100644 --- a/modules/fiftyonedegrees/devicedetection/module_test.go +++ b/modules/fiftyonedegrees/devicedetection/module_test.go @@ -12,8 +12,8 @@ import ( "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/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/modules/moduledeps" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -44,7 +44,7 @@ func (m *mockEvidenceExtractor) fromSuaPayload(payload []byte) []stringEvidence return args.Get(0).([]stringEvidence) } -func (m *mockEvidenceExtractor) extract(ctx hookstage.ModuleContext) ([]onpremise.Evidence, string, error) { +func (m *mockEvidenceExtractor) extract(ctx *hookstage.ModuleContext) ([]onpremise.Evidence, string, error) { args := m.Called(ctx) res := args.Get(0) @@ -131,16 +131,18 @@ func TestHandleEntrypointHookAccountAllowed(t *testing.T) { result, err := module.HandleEntrypointHook(nil, hookstage.ModuleInvocationContext{}, hookstage.EntrypointPayload{}) assert.NoError(t, err) + evidenceFromHeadersCtx, _ := result.ModuleContext.Get(evidenceFromHeadersCtxKey) assert.Equal( - t, result.ModuleContext[evidenceFromHeadersCtxKey], []stringEvidence{{ + t, evidenceFromHeadersCtx, []stringEvidence{{ Prefix: "123", Key: "key", Value: "val", }}, ) + evidenceFromSuaCtx, _ := result.ModuleContext.Get(evidenceFromSuaCtxKey) assert.Equal( - t, result.ModuleContext[evidenceFromSuaCtxKey], []stringEvidence{{ + t, evidenceFromSuaCtx, []stringEvidence{{ Prefix: "123", Key: "User-Agent", Value: "ua", @@ -179,9 +181,8 @@ func TestHandleRawAuctionHookExtractError(t *testing.T) { accountValidator: &mockValidator, } - mctx := make(hookstage.ModuleContext) - - mctx[ddEnabledCtxKey] = true + mctx := hookstage.NewModuleContext() + mctx.Set(ddEnabledCtxKey, true) result, err := module.HandleRawAuctionHook( context.TODO(), hookstage.ModuleInvocationContext{ @@ -252,7 +253,7 @@ func TestHandleRawAuctionHookEnrichment(t *testing.T) { deviceDetectorM.On("getDeviceInfo", mock.Anything, mock.Anything).Return( &deviceInfo{ HardwareVendor: "Apple", - HardwareName: "Macbook", + HardwareName: "Macbook Pro", DeviceType: "device", PlatformVendor: "Apple", PlatformName: "MacOs", @@ -268,6 +269,8 @@ func TestHandleRawAuctionHookEnrichment(t *testing.T) { HardwareFamily: "Macbook", HardwareModel: "Macbook", HardwareModelVariants: "Macbook", + HardwareNamePrefix: "Macbook", + HardwareNameVersion: "Pro", UserAgent: "ua", DeviceId: "", }, @@ -280,8 +283,8 @@ func TestHandleRawAuctionHookEnrichment(t *testing.T) { accountValidator: &mockValidator, } - mctx := make(hookstage.ModuleContext) - mctx[ddEnabledCtxKey] = true + mctx := hookstage.NewModuleContext() + mctx.Set(ddEnabledCtxKey, true) result, err := module.HandleRawAuctionHook( nil, hookstage.ModuleInvocationContext{ @@ -401,7 +404,7 @@ func TestHandleRawAuctionHookEnrichment(t *testing.T) { "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} + ,"devicetype":2,"ua":"ua","make":"Apple","model":"Macbook","hwv":"Pro","os":"MacOs","osv":"14","h":1080,"w":1024,"pxratio":223,"js":1,"geoFetch":1} }`) var deviceDetectorErrM mockDeviceDetector @@ -454,7 +457,7 @@ func TestHandleRawAuctionHookEnrichmentWithErrors(t *testing.T) { mockDeviceDetector.On("getDeviceInfo", mock.Anything, mock.Anything).Return( &deviceInfo{ HardwareVendor: "Apple", - HardwareName: "Macbook", + HardwareName: "Macbook Pro", DeviceType: "device", PlatformVendor: "Apple", PlatformName: "MacOs", @@ -470,6 +473,8 @@ func TestHandleRawAuctionHookEnrichmentWithErrors(t *testing.T) { HardwareFamily: "Macbook", HardwareModel: "Macbook", HardwareModelVariants: "Macbook", + HardwareNamePrefix: "Macbook", + HardwareNameVersion: "Pro", UserAgent: "ua", DeviceId: "", ScreenInchesHeight: 7, @@ -483,8 +488,8 @@ func TestHandleRawAuctionHookEnrichmentWithErrors(t *testing.T) { accountValidator: &mockValidator, } - mctx := make(hookstage.ModuleContext) - mctx[ddEnabledCtxKey] = true + mctx := hookstage.NewModuleContext() + mctx.Set(ddEnabledCtxKey, true) result, err := module.HandleRawAuctionHook( nil, hookstage.ModuleInvocationContext{ @@ -500,7 +505,7 @@ func TestHandleRawAuctionHookEnrichmentWithErrors(t *testing.T) { 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":""}}}`) + require.JSONEq(t, string(mutationResult), `{"device":{"devicetype":2,"ua":"ua","make":"Apple","model":"Macbook","hwv":"Pro","os":"MacOs","osv":"14","h":1080,"w":1024,"pxratio":223,"js":1,"geoFetch":1,"ppi":154,"ext":{"fiftyonedegrees_deviceId":""}}}`) } func TestConfigHashFromConfig(t *testing.T) { @@ -633,7 +638,7 @@ func TestBuilderHandleDeviceDetectorError(t *testing.T) { func TestHydrateFields(t *testing.T) { deviceInfo := &deviceInfo{ HardwareVendor: "Apple", - HardwareName: "Macbook", + HardwareName: "Macbook Pro", DeviceType: "device", PlatformVendor: "Apple", PlatformName: "MacOs", @@ -649,6 +654,8 @@ func TestHydrateFields(t *testing.T) { HardwareFamily: "Macbook", HardwareModel: "Macbook", HardwareModelVariants: "Macbook", + HardwareNamePrefix: "Macbook", + HardwareNameVersion: "Pro", UserAgent: "ua", DeviceId: "dev-ide", } @@ -699,7 +706,7 @@ func TestHydrateFields(t *testing.T) { 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}`, + `{"devicetype":2,"dnt":0,"ext":{"fiftyonedegrees_deviceId":"dev-ide","h":"901","w":843},"geoFetch":1,"h":901,"hwv":"Pro","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/no-cgo.go b/modules/fiftyonedegrees/devicedetection/no-cgo.go index c9ec89eb20..4fe5814f7a 100644 --- a/modules/fiftyonedegrees/devicedetection/no-cgo.go +++ b/modules/fiftyonedegrees/devicedetection/no-cgo.go @@ -6,7 +6,7 @@ import ( "encoding/json" "errors" - "github.com/prebid/prebid-server/v3/modules/moduledeps" + "github.com/prebid/prebid-server/v4/modules/moduledeps" ) const errMsg = "fiftyonedegrees should not be enabled unless CGO is enabled" diff --git a/modules/generator/builder.tmpl b/modules/generator/builder.tmpl index 211e0d1e08..ebf49e7615 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/v3/modules/{{$vendor}}/{{$module}}" + {{$vendor}}{{$module | Title}} "github.com/prebid/prebid-server/v4/modules/{{$vendor}}/{{$module}}" {{- end}} {{- end}} ) diff --git a/modules/helpers.go b/modules/helpers.go index 9a3c547e0b..66fb40a370 100644 --- a/modules/helpers.go +++ b/modules/helpers.go @@ -4,17 +4,17 @@ import ( "fmt" "strings" - "github.com/prebid/prebid-server/v3/hooks" - "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/hooks/hookstage" ) var moduleReplacer = strings.NewReplacer(".", "_", "-", "_") func createModuleStageNamesCollection(modules map[string]interface{}) (map[string][]string, error) { moduleStageNameCollector := make(map[string][]string) - var added bool for id, hook := range modules { + added := false if _, ok := hook.(hookstage.Entrypoint); ok { added = true stageName := hooks.StageEntrypoint.String() diff --git a/modules/moduledeps/deps.go b/modules/moduledeps/deps.go index a60587e1ef..5d15c4d510 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/v3/currency" + "github.com/prebid/prebid-server/v4/currency" ) // ModuleDeps provides dependencies that custom modules may need for hooks execution. diff --git a/modules/modules.go b/modules/modules.go index 288beb5b7b..cdca17ff8f 100644 --- a/modules/modules.go +++ b/modules/modules.go @@ -4,11 +4,11 @@ import ( "encoding/json" "fmt" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/hooks" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/modules/moduledeps" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/modules/moduledeps" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) //go:generate go run ./generator/buildergen.go diff --git a/modules/modules_test.go b/modules/modules_test.go index cdc573e992..e9a1102efd 100644 --- a/modules/modules_test.go +++ b/modules/modules_test.go @@ -9,10 +9,10 @@ import ( "net/http" "testing" - "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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/modules/moduledeps" "github.com/stretchr/testify/assert" ) diff --git a/modules/msp_plugin.go b/modules/msp_plugin.go index b69c0788b2..229e24ed33 100644 --- a/modules/msp_plugin.go +++ b/modules/msp_plugin.go @@ -5,9 +5,9 @@ import ( "fmt" "github.com/golang/glog" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/modules/moduledeps" - mspPlugin "github.com/prebid/prebid-server/v3/msp/plugin" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/modules/moduledeps" + mspPlugin "github.com/prebid/prebid-server/v4/msp/plugin" ) type PluginBuilder interface { diff --git a/modules/prebid/ortb2blocking/analytics.go b/modules/prebid/ortb2blocking/analytics.go index bab50e3a4e..de2b4db61f 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/v3/hooks/hookanalytics" - "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v4/hooks/hookanalytics" + "github.com/prebid/prebid-server/v4/hooks/hookstage" ) const enforceBlockingTag = "enforce_blocking" diff --git a/modules/prebid/ortb2blocking/config.go b/modules/prebid/ortb2blocking/config.go index 1990b0a56a..102b895f73 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/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) func newConfig(data json.RawMessage) (config, error) { @@ -84,13 +84,21 @@ type BtypeActionOverride struct { type Battr struct { ActionOverrides BattrActionOverride `json:"action_overrides"` AllowedBannerAttrForDeals []int `json:"allowed_banner_attr_for_deals"` + AllowedVideoAttrForDeals []int `json:"allowed_video_attr_for_deals"` + AllowedAudioAttrForDeals []int `json:"allowed_audio_attr_for_deals"` BlockedBannerAttr []int `json:"blocked_banner_attr"` + BlockedVideoAttr []int `json:"blocked_video_attr"` + BlockedAudioAttr []int `json:"blocked_audio_attr"` EnforceBlocks bool `json:"enforce_blocks"` } type BattrActionOverride struct { AllowedBannerAttrForDeals []ActionOverride `json:"allowed_banner_attr_for_deals"` + AllowedVideoAttrForDeals []ActionOverride `json:"allowed_video_attr_for_deals"` + AllowedAudioAttrForDeals []ActionOverride `json:"allowed_audio_attr_for_deals"` BlockedBannerAttr []ActionOverride `json:"blocked_banner_attr"` + BlockedVideoAttr []ActionOverride `json:"blocked_video_attr"` + BlockedAudioAttr []ActionOverride `json:"blocked_audio_attr"` EnforceBlocks []ActionOverride `json:"enforce_blocks"` } diff --git a/modules/prebid/ortb2blocking/hook_bidderrequest.go b/modules/prebid/ortb2blocking/hook_bidderrequest.go index 4b3cb87c85..9542777ae0 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/v3/hooks/hookexecution" - "github.com/prebid/prebid-server/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) func handleBidderRequestHook( @@ -47,7 +47,10 @@ func handleBidderRequestHook( updateCatTax(cfg, payload, &blockingAttributes, &changeSet) result.ChangeSet = changeSet - result.ModuleContext = hookstage.ModuleContext{payload.Bidder: blockingAttributes} + if result.ModuleContext == nil { + result.ModuleContext = hookstage.NewModuleContext() + } + result.ModuleContext.Set(payload.Bidder, blockingAttributes) return result, nil } @@ -147,13 +150,22 @@ func updateBType( return imp.Banner != nil && len(imp.Banner.BType) > 0 } - attributes.bType, messages, err = findImpressionOverrides(payload, actionOverrides, btype, checkAttrExistence) + overrides, messages, err := findImpressionOverrides(payload, actionOverrides, btype, checkAttrExistence) result.Warnings = mergeStrings(result.Warnings, messages...) if err != nil { return fmt.Errorf("failed to get override for imp.*.banner.btype: %s", err) - } else if len(attributes.bType) > 0 { - mutation := bTypeMutation(attributes.bType) - changeSet.AddMutation(mutation, hookstage.MutationUpdate, "bidrequest", "imp", "banner", "btype") + } + + // Filter to only apply to impressions with Banner objects + if len(overrides) > 0 { + filteredOverrides := filterByMediaType(payload, overrides, func(imp openrtb2.Imp) bool { + return imp.Banner != nil + }) + if len(filteredOverrides) > 0 { + mutation := createBTypeMutation(filteredOverrides) + changeSet.AddMutation(mutation, hookstage.MutationUpdate, "bidrequest", "imp", "banner", "btype") + } + attributes.bType = overrides } return nil @@ -167,21 +179,91 @@ func updateBAttr( changeSet *hookstage.ChangeSet[hookstage.BidderRequestPayload], ) (err error) { var messages []string - battr := cfg.Attributes.Battr.BlockedBannerAttr - actionOverrides := cfg.Attributes.Battr.ActionOverrides.BlockedBannerAttr - checkAttrExistence := func(imp openrtb2.Imp) bool { + + bannerBattr := cfg.Attributes.Battr.BlockedBannerAttr + bannerActionOverrides := cfg.Attributes.Battr.ActionOverrides.BlockedBannerAttr + bannerCheckAttrExistence := func(imp openrtb2.Imp) bool { return imp.Banner != nil && len(imp.Banner.BAttr) > 0 } - attributes.bAttr, messages, err = findImpressionOverrides(payload, actionOverrides, battr, checkAttrExistence) - result.Warnings = mergeStrings(result.Warnings, messages...) + bannerOverrides, bannerMessages, err := findImpressionOverrides(payload, bannerActionOverrides, bannerBattr, bannerCheckAttrExistence) + messages = append(messages, bannerMessages...) if err != nil { return fmt.Errorf("failed to get override for imp.*.banner.battr: %s", err) - } else if len(attributes.bAttr) > 0 { - mutation := bAttrMutation(attributes.bAttr) - changeSet.AddMutation(mutation, hookstage.MutationUpdate, "bidrequest", "imp", "banner", "battr") } + // Apply banner battr only to impressions that have Banner objects + if len(bannerOverrides) > 0 { + filteredBannerOverrides := filterByMediaType(payload, bannerOverrides, func(imp openrtb2.Imp) bool { + return imp.Banner != nil + }) + if len(filteredBannerOverrides) > 0 { + mutation := createBAttrMutation(filteredBannerOverrides, "banner") + changeSet.AddMutation(mutation, hookstage.MutationUpdate, "bidrequest", "imp", "banner", "battr") + } + } + + // Video battr + videoBattr := cfg.Attributes.Battr.BlockedVideoAttr + videoActionOverrides := cfg.Attributes.Battr.ActionOverrides.BlockedVideoAttr + videoCheckAttrExistence := func(imp openrtb2.Imp) bool { + return imp.Video != nil && len(imp.Video.BAttr) > 0 + } + + videoOverrides, videoMessages, err := findImpressionOverrides(payload, videoActionOverrides, videoBattr, videoCheckAttrExistence) + messages = append(messages, videoMessages...) + if err != nil { + return fmt.Errorf("failed to get override for imp.*.video.battr: %s", err) + } + + // Apply video battr only to impressions that have Video objects + if len(videoOverrides) > 0 { + filteredVideoOverrides := filterByMediaType(payload, videoOverrides, func(imp openrtb2.Imp) bool { + return imp.Video != nil + }) + if len(filteredVideoOverrides) > 0 { + mutation := createBAttrMutation(filteredVideoOverrides, "video") + changeSet.AddMutation(mutation, hookstage.MutationUpdate, "bidrequest", "imp", "video", "battr") + } + } + + // Audio battr + audioBattr := cfg.Attributes.Battr.BlockedAudioAttr + audioActionOverrides := cfg.Attributes.Battr.ActionOverrides.BlockedAudioAttr + audioCheckAttrExistence := func(imp openrtb2.Imp) bool { + return imp.Audio != nil && len(imp.Audio.BAttr) > 0 + } + + audioOverrides, audioMessages, err := findImpressionOverrides(payload, audioActionOverrides, audioBattr, audioCheckAttrExistence) + messages = append(messages, audioMessages...) + if err != nil { + return fmt.Errorf("failed to get override for imp.*.audio.battr: %s", err) + } + + // Apply audio battr only to impressions that have Audio objects + if len(audioOverrides) > 0 { + filteredAudioOverrides := filterByMediaType(payload, audioOverrides, func(imp openrtb2.Imp) bool { + return imp.Audio != nil + }) + if len(filteredAudioOverrides) > 0 { + mutation := createBAttrMutation(filteredAudioOverrides, "audio") + changeSet.AddMutation(mutation, hookstage.MutationUpdate, "bidrequest", "imp", "audio", "battr") + } + } + + // Store all attributes and merge messages + attributes.bAttr = make(map[string][]int) + for k, v := range bannerOverrides { + attributes.bAttr[k] = v + } + for k, v := range videoOverrides { + attributes.bAttr[k] = v + } + for k, v := range audioOverrides { + attributes.bAttr[k] = v + } + + result.Warnings = mergeStrings(result.Warnings, messages...) return nil } @@ -199,26 +281,6 @@ func updateCatTax( changeSet.BidderRequest().CatTax().Update(attributes.catTax) } -func bTypeMutation(bTypeByImp map[string][]int) hookstage.MutationFunc[hookstage.BidderRequestPayload] { - return mutationForImp(bTypeByImp, func(imp openrtb2.Imp, btype []int) openrtb2.Imp { - imp.Banner.BType = make([]openrtb2.BannerAdType, len(btype)) - for i := range btype { - imp.Banner.BType[i] = openrtb2.BannerAdType(btype[i]) - } - return imp - }) -} - -func bAttrMutation(bAttrByImp map[string][]int) hookstage.MutationFunc[hookstage.BidderRequestPayload] { - return mutationForImp(bAttrByImp, func(imp openrtb2.Imp, battr []int) openrtb2.Imp { - imp.Banner.BAttr = make([]adcom1.CreativeAttribute, len(battr)) - for i := range battr { - imp.Banner.BAttr[i] = adcom1.CreativeAttribute(battr[i]) - } - return imp - }) -} - type impUpdateFunc func(imp openrtb2.Imp, values []int) openrtb2.Imp func mutationForImp( @@ -422,3 +484,64 @@ func validateCondition(conditions Conditions) error { } return nil } + +// filterByMediaType filters overrides to only include impressions with a specific media type +func filterByMediaType( + payload hookstage.BidderRequestPayload, + overrides map[string][]int, + mediaTypeExists func(imp openrtb2.Imp) bool, +) map[string][]int { + filtered := make(map[string][]int) + + for _, imp := range payload.Request.Imp { + if values, exists := overrides[imp.ID]; exists && mediaTypeExists(imp) { + filtered[imp.ID] = values + } + } + + return filtered +} + +// createBAttrMutation creates a mutation function for a specific media type +func createBAttrMutation(bAttrByImp map[string][]int, mediaType string) hookstage.MutationFunc[hookstage.BidderRequestPayload] { + return func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) { + for i, imp := range payload.Request.Imp { + if values, ok := bAttrByImp[imp.ID]; ok && len(values) > 0 { + switch mediaType { + case "banner": + imp.Banner.BAttr = make([]adcom1.CreativeAttribute, len(values)) + for j, attr := range values { + imp.Banner.BAttr[j] = adcom1.CreativeAttribute(attr) + } + case "video": + imp.Video.BAttr = make([]adcom1.CreativeAttribute, len(values)) + for j, attr := range values { + imp.Video.BAttr[j] = adcom1.CreativeAttribute(attr) + } + case "audio": + imp.Audio.BAttr = make([]adcom1.CreativeAttribute, len(values)) + for j, attr := range values { + imp.Audio.BAttr[j] = adcom1.CreativeAttribute(attr) + } + } + payload.Request.Imp[i] = imp + } + } + return payload, nil + } +} + +func createBTypeMutation(bTypeByImp map[string][]int) hookstage.MutationFunc[hookstage.BidderRequestPayload] { + return func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) { + for i, imp := range payload.Request.Imp { + if values, ok := bTypeByImp[imp.ID]; ok && len(values) > 0 { + imp.Banner.BType = make([]openrtb2.BannerAdType, len(values)) + for j, btype := range values { + imp.Banner.BType[j] = openrtb2.BannerAdType(btype) + } + payload.Request.Imp[i] = imp + } + } + return payload, nil + } +} diff --git a/modules/prebid/ortb2blocking/hook_bidderrequest_test.go b/modules/prebid/ortb2blocking/hook_bidderrequest_test.go new file mode 100644 index 0000000000..82ad708803 --- /dev/null +++ b/modules/prebid/ortb2blocking/hook_bidderrequest_test.go @@ -0,0 +1,738 @@ +package ortb2blocking + +import ( + "testing" + + "github.com/prebid/openrtb/v20/adcom1" + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestUpdateBAttr_DoesNotCreateMediaTypeObjects(t *testing.T) { + cfg := config{ + Attributes: Attributes{ + Battr: Battr{ + BlockedBannerAttr: []int{1, 2, 3}, + BlockedVideoAttr: []int{4, 5, 6}, + BlockedAudioAttr: []int{7, 8, 9}, + }, + }, + } + + var sizeW int64 = 640 + var sizeH int64 = 480 + + payload := hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp-video-only", + Video: &openrtb2.Video{W: &sizeW, H: &sizeH}, + // Banner = nil, Audio = nil + }, + { + ID: "imp-audio-only", + Audio: &openrtb2.Audio{}, + // Banner = nil, Video = nil + }, + }, + }, + }, + Bidder: "test-bidder", + } + + var blockingAttrs blockingAttributes + var result hookstage.HookResult[hookstage.BidderRequestPayload] + var changeSet hookstage.ChangeSet[hookstage.BidderRequestPayload] + + err := updateBAttr(cfg, payload, &blockingAttrs, &result, &changeSet) + require.NoError(t, err) + + // Check that mutations were created only for existing media types + mutations := changeSet.Mutations() + + // Check the number of mutations - there should be only one for video and one for audio + videoMutationsCount := 0 + audioMutationsCount := 0 + bannerMutationsCount := 0 + + for _, mutation := range mutations { + if len(mutation.Key()) >= 3 { + mediaType := mutation.Key()[2] // the third path element must be a media type + switch mediaType { + case "video": + videoMutationsCount++ + case "audio": + audioMutationsCount++ + case "banner": + bannerMutationsCount++ + } + } + } + + assert.Equal(t, 1, videoMutationsCount, "Should have exactly one video mutation") + assert.Equal(t, 1, audioMutationsCount, "Should have exactly one audio mutation") + assert.Equal(t, 0, bannerMutationsCount, "Should have no banner mutations") + + // Apply mutations manually using functions from the code + for _, mutation := range mutations { + updatedPayload, err := mutation.Apply(payload) + require.NoError(t, err) + payload = updatedPayload + } + + // Check that Banner/Audio objects were NOT created + for _, imp := range payload.Request.BidRequest.Imp { + switch imp.ID { + case "imp-video-only": + assert.NotNil(t, imp.Video, "Video should exist") + assert.Nil(t, imp.Banner, "Banner should NOT be created") + assert.Nil(t, imp.Audio, "Audio should NOT be created") + // Check that battr was added to video + if imp.Video != nil { + assert.Len(t, imp.Video.BAttr, 3, "Video should have battr applied") + } + case "imp-audio-only": + assert.NotNil(t, imp.Audio, "Audio should exist") + assert.Nil(t, imp.Banner, "Banner should NOT be created") + assert.Nil(t, imp.Video, "Video should NOT be created") + // Check that battr was added to audio + if imp.Audio != nil { + assert.Len(t, imp.Audio.BAttr, 3, "Audio should have battr applied") + } + } + } +} + +func TestUpdateBAttr_AppliesOnlyToExistingMediaTypes(t *testing.T) { + cfg := config{ + Attributes: Attributes{ + Battr: Battr{ + BlockedBannerAttr: []int{1, 2}, + BlockedVideoAttr: []int{3, 4}, + BlockedAudioAttr: []int{5, 6}, + }, + }, + } + + payload := hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp-banner-only", + Banner: &openrtb2.Banner{W: ptrutil.ToPtr[int64](300), H: ptrutil.ToPtr[int64](250)}, + }, + { + ID: "imp-mixed", + Banner: &openrtb2.Banner{W: ptrutil.ToPtr[int64](728), H: ptrutil.ToPtr[int64](90)}, + Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](640), H: ptrutil.ToPtr[int64](480)}, + }, + }, + }, + }, + Bidder: "test-bidder", + } + + var blockingAttrs blockingAttributes + var result hookstage.HookResult[hookstage.BidderRequestPayload] + var changeSet hookstage.ChangeSet[hookstage.BidderRequestPayload] + + err := updateBAttr(cfg, payload, &blockingAttrs, &result, &changeSet) + require.NoError(t, err) + + // We apply mutations + mutations := changeSet.Mutations() + for _, mutation := range mutations { + updatedPayload, err := mutation.Apply(payload) + require.NoError(t, err) + payload = updatedPayload + } + + for _, imp := range payload.Request.BidRequest.Imp { + switch imp.ID { + case "imp-banner-only": + assert.NotNil(t, imp.Banner, "Banner should exist") + assert.Nil(t, imp.Video, "Video should NOT be created") + assert.Nil(t, imp.Audio, "Audio should NOT be created") + if imp.Banner != nil { + assert.Len(t, imp.Banner.BAttr, 2, "Banner should have battr applied") + } + case "imp-mixed": + assert.NotNil(t, imp.Banner, "Banner should exist") + assert.NotNil(t, imp.Video, "Video should exist") + assert.Nil(t, imp.Audio, "Audio should NOT be created") + if imp.Banner != nil { + assert.Len(t, imp.Banner.BAttr, 2, "Banner should have battr applied") + } + if imp.Video != nil { + assert.Len(t, imp.Video.BAttr, 2, "Video should have battr applied") + } + } + } +} + +func TestFilterByMediaType(t *testing.T) { + payload := hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "has-banner", + Banner: &openrtb2.Banner{}, + }, + { + ID: "no-banner", + // Banner = nil + }, + }, + }, + }, + } + + overrides := map[string][]int{ + "has-banner": {1, 2, 3}, + "no-banner": {4, 5, 6}, + } + + filtered := filterByMediaType(payload, overrides, func(imp openrtb2.Imp) bool { + return imp.Banner != nil + }) + + // Only the impression with the Banner should remain. + assert.Len(t, filtered, 1) + assert.Contains(t, filtered, "has-banner") + assert.NotContains(t, filtered, "no-banner") + assert.Equal(t, []int{1, 2, 3}, filtered["has-banner"]) +} + +func TestCreateBAttrMutation(t *testing.T) { + bAttrByImp := map[string][]int{ + "imp1": {1, 2}, + "imp2": {3, 4}, + } + + payload := hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp1", + Banner: &openrtb2.Banner{}, + }, + { + ID: "imp2", + Banner: &openrtb2.Banner{}, + }, + }, + }, + }, + } + + mutation := createBAttrMutation(bAttrByImp, "banner") + updatedPayload, err := mutation(payload) + require.NoError(t, err) + + // Check that battr was applied + for _, imp := range updatedPayload.Request.BidRequest.Imp { + switch imp.ID { + case "imp1": + require.NotNil(t, imp.Banner) + assert.Len(t, imp.Banner.BAttr, 2) + assert.Equal(t, adcom1.CreativeAttribute(1), imp.Banner.BAttr[0]) + assert.Equal(t, adcom1.CreativeAttribute(2), imp.Banner.BAttr[1]) + case "imp2": + require.NotNil(t, imp.Banner) + assert.Len(t, imp.Banner.BAttr, 2) + assert.Equal(t, adcom1.CreativeAttribute(3), imp.Banner.BAttr[0]) + assert.Equal(t, adcom1.CreativeAttribute(4), imp.Banner.BAttr[1]) + } + } +} + +func TestCreateBTypeMutation(t *testing.T) { + bTypeByImp := map[string][]int{ + "imp1": {1, 2}, + "imp2": {3, 4}, + } + + payload := hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp1", + Banner: &openrtb2.Banner{}, + }, + { + ID: "imp2", + Banner: &openrtb2.Banner{}, + }, + }, + }, + }, + } + + mutation := createBTypeMutation(bTypeByImp) + updatedPayload, err := mutation(payload) + require.NoError(t, err) + + // Check that btype was applied + for _, imp := range updatedPayload.Request.BidRequest.Imp { + switch imp.ID { + case "imp1": + require.NotNil(t, imp.Banner) + assert.Len(t, imp.Banner.BType, 2) + assert.Equal(t, openrtb2.BannerAdType(1), imp.Banner.BType[0]) + assert.Equal(t, openrtb2.BannerAdType(2), imp.Banner.BType[1]) + case "imp2": + require.NotNil(t, imp.Banner) + assert.Len(t, imp.Banner.BType, 2) + assert.Equal(t, openrtb2.BannerAdType(3), imp.Banner.BType[0]) + assert.Equal(t, openrtb2.BannerAdType(4), imp.Banner.BType[1]) + } + } +} + +func TestUpdateBType_DoesNotCreateBannerObjects(t *testing.T) { + cfg := config{ + Attributes: Attributes{ + Btype: Btype{ + BlockedBannerType: []int{1, 2, 3}, + }, + }, + } + + payload := hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp-video-only", + Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](640), H: ptrutil.ToPtr[int64](480)}, + }, + { + ID: "imp-with-banner", + Banner: &openrtb2.Banner{}, + }, + }, + }, + }, + Bidder: "test-bidder", + } + + var blockingAttrs blockingAttributes + var result hookstage.HookResult[hookstage.BidderRequestPayload] + var changeSet hookstage.ChangeSet[hookstage.BidderRequestPayload] + + err := updateBType(cfg, payload, &blockingAttrs, &result, &changeSet) + require.NoError(t, err) + + // Apply mutations + mutations := changeSet.Mutations() + for _, mutation := range mutations { + updatedPayload, err := mutation.Apply(payload) + require.NoError(t, err) + payload = updatedPayload + } + + // Check that Banner was NOT created for video-only impression + for _, imp := range payload.Request.BidRequest.Imp { + switch imp.ID { + case "imp-video-only": + assert.NotNil(t, imp.Video, "Video should exist") + assert.Nil(t, imp.Banner, "Banner should NOT be created") + case "imp-with-banner": + assert.NotNil(t, imp.Banner, "Banner should exist") + assert.Len(t, imp.Banner.BType, 3, "Banner should have btype applied") + } + } +} + +func TestCreateBAttrMutation_EmptyValues(t *testing.T) { + bAttrByImp := map[string][]int{ + "imp1": {}, + "imp2": {1, 2}, + } + + payload := hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp1", + Banner: &openrtb2.Banner{}, + }, + { + ID: "imp2", + Banner: &openrtb2.Banner{}, + }, + }, + }, + }, + } + + mutation := createBAttrMutation(bAttrByImp, "banner") + updatedPayload, err := mutation(payload) + require.NoError(t, err) + + // Check that empty values are handled correctly + for _, imp := range updatedPayload.Request.BidRequest.Imp { + switch imp.ID { + case "imp1": + require.NotNil(t, imp.Banner) + // Empty array should result in empty BAttr + assert.Len(t, imp.Banner.BAttr, 0) + case "imp2": + require.NotNil(t, imp.Banner) + assert.Len(t, imp.Banner.BAttr, 2) + } + } +} + +func TestCreateBTypeMutation_EmptyValues(t *testing.T) { + bTypeByImp := map[string][]int{ + "imp1": {}, + "imp2": {1, 2}, + } + + payload := hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp1", + Banner: &openrtb2.Banner{}, + }, + { + ID: "imp2", + Banner: &openrtb2.Banner{}, + }, + }, + }, + }, + } + + mutation := createBTypeMutation(bTypeByImp) + updatedPayload, err := mutation(payload) + require.NoError(t, err) + + for _, imp := range updatedPayload.Request.BidRequest.Imp { + switch imp.ID { + case "imp1": + require.NotNil(t, imp.Banner) + assert.Len(t, imp.Banner.BType, 0) + case "imp2": + require.NotNil(t, imp.Banner) + assert.Len(t, imp.Banner.BType, 2) + } + } +} + +func TestMediaTypesFrom(t *testing.T) { + request := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp1", + Banner: &openrtb2.Banner{}, + Video: &openrtb2.Video{}, + }, + { + ID: "imp2", + Audio: &openrtb2.Audio{}, + }, + }, + } + + mediaTypes := mediaTypesFrom(request) + + assert.Len(t, mediaTypes, 3) + assert.Contains(t, mediaTypes, "banner") + assert.Contains(t, mediaTypes, "video") + assert.Contains(t, mediaTypes, "audio") + assert.NotContains(t, mediaTypes, "native") +} + +func TestMediaTypesFromImp(t *testing.T) { + tests := []struct { + name string + imp openrtb2.Imp + expected []string + }{ + { + name: "banner only", + imp: openrtb2.Imp{ + Banner: &openrtb2.Banner{}, + }, + expected: []string{"banner"}, + }, + { + name: "video only", + imp: openrtb2.Imp{ + Video: &openrtb2.Video{}, + }, + expected: []string{"video"}, + }, + { + name: "audio only", + imp: openrtb2.Imp{ + Audio: &openrtb2.Audio{}, + }, + expected: []string{"audio"}, + }, + { + name: "native only", + imp: openrtb2.Imp{ + Native: &openrtb2.Native{}, + }, + expected: []string{"native"}, + }, + { + name: "multiple types", + imp: openrtb2.Imp{ + Banner: &openrtb2.Banner{}, + Video: &openrtb2.Video{}, + Audio: &openrtb2.Audio{}, + }, + expected: []string{"banner", "video", "audio"}, + }, + { + name: "no media types", + imp: openrtb2.Imp{}, + expected: []string{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := mediaTypesFromImp(tt.imp) + assert.Len(t, result, len(tt.expected)) + for _, mt := range tt.expected { + assert.Contains(t, result, mt) + } + }) + } +} + +func TestMediaTypes_String(t *testing.T) { + tests := []struct { + name string + mt mediaTypes + expected string + }{ + { + name: "multiple types sorted", + mt: mediaTypes{ + "video": struct{}{}, + "banner": struct{}{}, + "audio": struct{}{}, + }, + expected: "audio, banner, video", + }, + { + name: "empty", + mt: mediaTypes{}, + expected: "", + }, + { + name: "all types", + mt: mediaTypes{ + "audio": struct{}{}, + "banner": struct{}{}, + "native": struct{}{}, + "video": struct{}{}, + }, + expected: "audio, banner, native, video", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.mt.String() + assert.Equal(t, tt.expected, result) + }) + } +} + +func TestMediaTypes_Intersects(t *testing.T) { + mt := mediaTypes{ + "banner": struct{}{}, + "video": struct{}{}, + } + + tests := []struct { + name string + input []string + expected bool + }{ + { + name: "exact match", + input: []string{"banner"}, + expected: true, + }, + { + name: "case insensitive match", + input: []string{"BANNER"}, + expected: true, + }, + { + name: "multiple with match", + input: []string{"audio", "video"}, + expected: true, + }, + { + name: "no match", + input: []string{"audio", "native"}, + expected: false, + }, + { + name: "empty input", + input: []string{}, + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := mt.intersects(tt.input) + assert.Equal(t, tt.expected, result) + }) + } +} + +func TestValidateCondition(t *testing.T) { + tests := []struct { + name string + condition Conditions + wantErr bool + }{ + { + name: "valid - bidders only", + condition: Conditions{ + Bidders: []string{"bidder1"}, + }, + wantErr: false, + }, + { + name: "valid - media types only", + condition: Conditions{ + MediaTypes: []string{"banner"}, + }, + wantErr: false, + }, + { + name: "valid - both present", + condition: Conditions{ + Bidders: []string{"bidder1"}, + MediaTypes: []string{"banner"}, + }, + wantErr: false, + }, + { + name: "invalid - both absent", + condition: Conditions{}, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateCondition(tt.condition) + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestFilterByMediaType_NoMatches(t *testing.T) { + payload := hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp1", + Video: &openrtb2.Video{}, + }, + }, + }, + }, + } + + overrides := map[string][]int{ + "imp1": {1, 2, 3}, + } + + // Filter for Banner, but impression has only Video + filtered := filterByMediaType(payload, overrides, func(imp openrtb2.Imp) bool { + return imp.Banner != nil + }) + + assert.Len(t, filtered, 0, "Should not include impressions without matching media type") +} + +func TestCreateBAttrMutation_VideoMediaType(t *testing.T) { + bAttrByImp := map[string][]int{ + "imp1": {1, 2}, + } + + payload := hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp1", + Video: &openrtb2.Video{}, + }, + }, + }, + }, + } + + mutation := createBAttrMutation(bAttrByImp, "video") + updatedPayload, err := mutation(payload) + require.NoError(t, err) + + imp := updatedPayload.Request.BidRequest.Imp[0] + require.NotNil(t, imp.Video) + assert.Len(t, imp.Video.BAttr, 2) + assert.Equal(t, adcom1.CreativeAttribute(1), imp.Video.BAttr[0]) + assert.Equal(t, adcom1.CreativeAttribute(2), imp.Video.BAttr[1]) +} + +func TestCreateBAttrMutation_AudioMediaType(t *testing.T) { + bAttrByImp := map[string][]int{ + "imp1": {7, 8, 9}, + } + + payload := hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "imp1", + Audio: &openrtb2.Audio{}, + }, + }, + }, + }, + } + + mutation := createBAttrMutation(bAttrByImp, "audio") + updatedPayload, err := mutation(payload) + require.NoError(t, err) + + imp := updatedPayload.Request.BidRequest.Imp[0] + require.NotNil(t, imp.Audio) + assert.Len(t, imp.Audio.BAttr, 3) + assert.Equal(t, adcom1.CreativeAttribute(7), imp.Audio.BAttr[0]) + assert.Equal(t, adcom1.CreativeAttribute(8), imp.Audio.BAttr[1]) + assert.Equal(t, adcom1.CreativeAttribute(9), imp.Audio.BAttr[2]) +} diff --git a/modules/prebid/ortb2blocking/hook_raw_bidder_response.go b/modules/prebid/ortb2blocking/hook_raw_bidder_response.go index a6ddbdd58c..cbdae93735 100644 --- a/modules/prebid/ortb2blocking/hook_raw_bidder_response.go +++ b/modules/prebid/ortb2blocking/hook_raw_bidder_response.go @@ -7,18 +7,18 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/adapters" - "github.com/prebid/prebid-server/v3/hooks/hookexecution" - "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/hooks/hookstage" ) func handleRawBidderResponseHook( cfg config, payload hookstage.RawBidderResponsePayload, - moduleCtx hookstage.ModuleContext, + moduleCtx *hookstage.ModuleContext, ) (result hookstage.HookResult[hookstage.RawBidderResponsePayload], err error) { bidder := payload.Bidder - blockAttrsVal, ok := moduleCtx[bidder] + blockAttrsVal, ok := moduleCtx.Get(bidder) if !ok { // if there are no blocking attributes for this bidder just pass empty blockingAttributes for further processing // other values from config must still be checked diff --git a/modules/prebid/ortb2blocking/module.go b/modules/prebid/ortb2blocking/module.go index 24ff28df74..e31c7ccb7e 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/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/modules/moduledeps" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/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 17008b2dad..85be537bb6 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/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/prebid/prebid-server/v4/adapters" + "github.com/prebid/prebid-server/v4/hooks/hookanalytics" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/modules/moduledeps" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -307,8 +307,9 @@ func TestHandleBidderRequestHook(t *testing.T) { Video: &openrtb2.Video{}, }, { - ID: "ImpID2", - Audio: &openrtb2.Audio{}, + ID: "ImpID2", + Audio: &openrtb2.Audio{}, + Banner: &openrtb2.Banner{}, }, }, }, @@ -342,8 +343,9 @@ func TestHandleBidderRequestHook(t *testing.T) { }, }, expectedHookResult: hookstage.HookResult[hookstage.BidderRequestPayload]{ - ModuleContext: map[string]interface{}{ - bidder: blockingAttributes{ + ModuleContext: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{ bAdv: []string{bAdvA, bAdvB}, bApp: []string{bApp3}, bCat: []string{bCat1, bCat2, bCat3, bCat4}, @@ -356,8 +358,9 @@ func TestHandleBidderRequestHook(t *testing.T) { "ImpID2": toInt([]adcom1.CreativeAttribute{bAttr1, bAttr8, bAttr9, bAttr10}), }, catTax: catTax, - }, - }, + }) + return mctx + }(), Warnings: []string{ // multiple warnings may be added (per condition) "More than one condition matches request. Bidder: appnexus, request media types: audio, banner, native, video", @@ -388,13 +391,14 @@ func TestHandleBidderRequestHook(t *testing.T) { }, }, expectedHookResult: hookstage.HookResult[hookstage.BidderRequestPayload]{ - ModuleContext: map[string]interface{}{ - bidder: blockingAttributes{ + ModuleContext: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{ bAdv: []string{bAdvA, bAdvB, bAdvC}, - bType: map[string][]int{}, bAttr: map[string][]int{}, - }, - }, + }) + return mctx + }(), }, expectedError: nil, }, @@ -439,10 +443,13 @@ func TestHandleBidderRequestHook(t *testing.T) { }, }, expectedHookResult: hookstage.HookResult[hookstage.BidderRequestPayload]{ - ModuleContext: map[string]interface{}{bidder: blockingAttributes{ - bType: map[string][]int{}, - bAttr: map[string][]int{}, - }}, + ModuleContext: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{ + bAttr: map[string][]int{}, + }) + return mctx + }(), }, expectedError: nil, }, @@ -460,10 +467,13 @@ func TestHandleBidderRequestHook(t *testing.T) { Imp: []openrtb2.Imp{{ID: "ImpID1", Video: &openrtb2.Video{}}}, }, expectedHookResult: hookstage.HookResult[hookstage.BidderRequestPayload]{ - ModuleContext: map[string]interface{}{bidder: blockingAttributes{ - bType: map[string][]int{}, - bAttr: map[string][]int{}, - }}, + ModuleContext: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{ + bAttr: map[string][]int{}, + }) + return mctx + }(), }, expectedError: nil, }, @@ -581,7 +591,7 @@ func TestHandleBidderRequestHook(t *testing.T) { hookstage.ModuleInvocationContext{ AccountConfig: test.config, Endpoint: hookexecution.EndpointAuction, - ModuleContext: map[string]interface{}{}, + ModuleContext: hookstage.NewModuleContext(), }, payload, ) @@ -607,7 +617,7 @@ func TestHandleRawBidderResponseHook(t *testing.T) { description string payload hookstage.RawBidderResponsePayload config json.RawMessage - moduleCtx hookstage.ModuleContext + moduleCtx *hookstage.ModuleContext expectedBids []*adapters.TypedBid expectedHookResult hookstage.HookResult[hookstage.RawBidderResponsePayload] expectedError error @@ -657,7 +667,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ADomain: []string{"foo"}, ImpID: impID1}, }, }, - moduleCtx: map[string]interface{}{bidder: "boo"}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, "boo") + return mctx + }(), expectedError: hookexecution.NewFailure("could not cast blocking attributes for bidder `appnexus`, module context has incorrect data"), }, { @@ -678,7 +692,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ID: "2", ADomain: []string{"good_domain"}, ImpID: impID2}, }, }, - moduleCtx: map[string]interface{}{bidder: blockingAttributes{bAdv: []string{"forbidden_domain"}}}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{bAdv: []string{"forbidden_domain"}}) + return mctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ @@ -726,7 +744,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ID: "2", ADomain: []string{"good_domain"}, ImpID: impID2}, }, }, - moduleCtx: map[string]interface{}{"other-bidder": blockingAttributes{bAdv: []string{"forbidden_domain"}}}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set("other-bidder", blockingAttributes{bAdv: []string{"forbidden_domain"}}) + return mctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ @@ -769,7 +791,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ID: "2", ADomain: []string{"good_domain"}, ImpID: impID2}, }, }, - moduleCtx: map[string]interface{}{bidder: blockingAttributes{bAdv: []string{"forbidden_domain"}}}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{bAdv: []string{"forbidden_domain"}}) + return mctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ @@ -812,7 +838,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ID: "2", ADomain: []string{"good_domain"}, ImpID: impID2}, }, }, - moduleCtx: map[string]interface{}{bidder: blockingAttributes{bAdv: []string{"forbidden_domain"}}}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{bAdv: []string{"forbidden_domain"}}) + return mctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ @@ -852,7 +882,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ID: "2", ADomain: []string{"good_domain"}, ImpID: impID2}, }, }, - moduleCtx: map[string]interface{}{bidder: blockingAttributes{}}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{}) + return mctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ @@ -900,7 +934,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ID: "2", ImpID: impID2}, }, }, - moduleCtx: map[string]interface{}{bidder: blockingAttributes{}}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{}) + return mctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ @@ -943,7 +981,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ID: "2", ADomain: []string{"good_domain"}, ImpID: impID2}, }, }, - moduleCtx: map[string]interface{}{bidder: blockingAttributes{bAdv: []string{"forbidden_domain"}}}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{bAdv: []string{"forbidden_domain"}}) + return mctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ @@ -1064,7 +1106,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ID: "2", Cat: []string{"moto"}, ImpID: impID2}, }, }, - moduleCtx: map[string]interface{}{bidder: blockingAttributes{bCat: []string{"fishing"}}}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{bCat: []string{"fishing"}}) + return mctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ @@ -1190,7 +1236,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ID: "2", CatTax: 2, ImpID: impID2}, }, }, - moduleCtx: map[string]interface{}{bidder: blockingAttributes{catTax: 2}}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{catTax: 2}) + return mctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ @@ -1279,7 +1329,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ID: "2", Bundle: "allowed_bundle", ImpID: impID2}, }, }, - moduleCtx: map[string]interface{}{bidder: blockingAttributes{bApp: []string{"forbidden_bundle"}}}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{bApp: []string{"forbidden_bundle"}}) + return mctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ @@ -1378,7 +1432,11 @@ func TestHandleRawBidderResponseHook(t *testing.T) { Bid: &openrtb2.Bid{ID: "2", Attr: []adcom1.CreativeAttribute{2}, ImpID: impID2}, }, }, - moduleCtx: map[string]interface{}{bidder: blockingAttributes{bAttr: map[string][]int{impID1: {1}}}}, + moduleCtx: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set(bidder, blockingAttributes{bAttr: map[string][]int{impID1: {1}}}) + return mctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ @@ -1501,13 +1559,17 @@ func TestHandleRawBidderResponseHook(t *testing.T) { }, }, }, - moduleCtx: map[string]interface{}{bidder: blockingAttributes{ - bAdv: []string{"forbidden_domain"}, - bCat: []string{"fishing"}, - catTax: 2, - bApp: []string{"forbidden_bundle"}, - bAttr: map[string][]int{impID1: {1}}}, - }, + moduleCtx: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(bidder, blockingAttributes{ + bAdv: []string{"forbidden_domain"}, + bCat: []string{"fishing"}, + catTax: 2, + bApp: []string{"forbidden_bundle"}, + bAttr: map[string][]int{impID1: {1}}, + }) + return ctx + }(), expectedHookResult: hookstage.HookResult[hookstage.RawBidderResponsePayload]{ AnalyticsTags: hookanalytics.Analytics{ Activities: []hookanalytics.Activity{ diff --git a/modules/prebid/rulesengine/bidder_config_ruleset.go b/modules/prebid/rulesengine/bidder_config_ruleset.go index 888c41c696..59d2c0079b 100644 --- a/modules/prebid/rulesengine/bidder_config_ruleset.go +++ b/modules/prebid/rulesengine/bidder_config_ruleset.go @@ -1,7 +1,7 @@ package rulesengine import ( - "github.com/prebid/prebid-server/v3/rules" + "github.com/prebid/prebid-server/v4/rules" ) // buildBidderConfigRuleSet builds a dynamic ruleset based on the geoscope annotations in the diff --git a/modules/prebid/rulesengine/bidder_config_ruleset_builder.go b/modules/prebid/rulesengine/bidder_config_ruleset_builder.go index 2fe9b705c6..85eb01753c 100644 --- a/modules/prebid/rulesengine/bidder_config_ruleset_builder.go +++ b/modules/prebid/rulesengine/bidder_config_ruleset_builder.go @@ -6,8 +6,8 @@ import ( "slices" "strings" - "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine/config" - "github.com/prebid/prebid-server/v3/rules" + "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine/config" + "github.com/prebid/prebid-server/v4/rules" ) type CountryExclusions = map[string][]string diff --git a/modules/prebid/rulesengine/bidder_config_ruleset_builder_test.go b/modules/prebid/rulesengine/bidder_config_ruleset_builder_test.go index e9f9743aff..709fe3156b 100644 --- a/modules/prebid/rulesengine/bidder_config_ruleset_builder_test.go +++ b/modules/prebid/rulesengine/bidder_config_ruleset_builder_test.go @@ -3,7 +3,7 @@ package rulesengine import ( "testing" - "github.com/prebid/prebid-server/v3/rules" + "github.com/prebid/prebid-server/v4/rules" "github.com/stretchr/testify/assert" ) diff --git a/modules/prebid/rulesengine/bidder_config_ruleset_test.go b/modules/prebid/rulesengine/bidder_config_ruleset_test.go index 93af63cd21..0813028930 100644 --- a/modules/prebid/rulesengine/bidder_config_ruleset_test.go +++ b/modules/prebid/rulesengine/bidder_config_ruleset_test.go @@ -4,8 +4,8 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine/config" - "github.com/prebid/prebid-server/v3/rules" + "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine/config" + "github.com/prebid/prebid-server/v4/rules" "github.com/stretchr/testify/assert" ) diff --git a/modules/prebid/rulesengine/cache.go b/modules/prebid/rulesengine/cache.go index 1b09abc1c5..2110b0cd6a 100644 --- a/modules/prebid/rulesengine/cache.go +++ b/modules/prebid/rulesengine/cache.go @@ -5,7 +5,7 @@ import ( "sync/atomic" "time" - "github.com/prebid/prebid-server/v3/util/timeutil" + "github.com/prebid/prebid-server/v4/util/timeutil" ) type accountID = string diff --git a/modules/prebid/rulesengine/cache_entry.go b/modules/prebid/rulesengine/cache_entry.go index 5b995dd6e7..5f912d1827 100644 --- a/modules/prebid/rulesengine/cache_entry.go +++ b/modules/prebid/rulesengine/cache_entry.go @@ -7,10 +7,10 @@ import ( "errors" "time" - "github.com/prebid/prebid-server/v3/hooks" - "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/rules" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/rules" ) type hash = string diff --git a/modules/prebid/rulesengine/cache_entry_test.go b/modules/prebid/rulesengine/cache_entry_test.go index 481f1a26c0..0b3cb8d7dd 100644 --- a/modules/prebid/rulesengine/cache_entry_test.go +++ b/modules/prebid/rulesengine/cache_entry_test.go @@ -5,10 +5,10 @@ import ( "errors" "testing" - "github.com/prebid/prebid-server/v3/hooks" - "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/rules" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/rules" "github.com/stretchr/testify/assert" ) diff --git a/modules/prebid/rulesengine/config/config.go b/modules/prebid/rulesengine/config/config.go index 0dc4bded5d..5654d20441 100644 --- a/modules/prebid/rulesengine/config/config.go +++ b/modules/prebid/rulesengine/config/config.go @@ -7,8 +7,8 @@ import ( "fmt" "path/filepath" - "github.com/prebid/prebid-server/v3/hooks" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/xeipuuv/gojsonschema" ) diff --git a/modules/prebid/rulesengine/hook_processed_auction.go b/modules/prebid/rulesengine/hook_processed_auction.go index 144b72a943..dad6891353 100644 --- a/modules/prebid/rulesengine/hook_processed_auction.go +++ b/modules/prebid/rulesengine/hook_processed_auction.go @@ -3,9 +3,9 @@ package rulesengine import ( "fmt" - hs "github.com/prebid/prebid-server/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/randomutil" + hs "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/randomutil" ) type RequestWrapper = openrtb_ext.RequestWrapper diff --git a/modules/prebid/rulesengine/hook_processed_auction_test.go b/modules/prebid/rulesengine/hook_processed_auction_test.go index 9cc5fc7f8e..7116644195 100644 --- a/modules/prebid/rulesengine/hook_processed_auction_test.go +++ b/modules/prebid/rulesengine/hook_processed_auction_test.go @@ -2,9 +2,9 @@ package rulesengine import ( "fmt" - hs "github.com/prebid/prebid-server/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/rules" + hs "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/rules" "testing" "github.com/stretchr/testify/assert" diff --git a/modules/prebid/rulesengine/module.go b/modules/prebid/rulesengine/module.go index ca63c763b9..e0a59245ed 100644 --- a/modules/prebid/rulesengine/module.go +++ b/modules/prebid/rulesengine/module.go @@ -8,9 +8,9 @@ import ( "github.com/buger/jsonparser" - hs "github.com/prebid/prebid-server/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/modules/moduledeps" - "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine/config" + hs "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/modules/moduledeps" + "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine/config" ) // Builder configures the rules engine module initiating an in-memory cache and kicking diff --git a/modules/prebid/rulesengine/module_test.go b/modules/prebid/rulesengine/module_test.go index 2cf2bd59bb..9bffeb8816 100644 --- a/modules/prebid/rulesengine/module_test.go +++ b/modules/prebid/rulesengine/module_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v3/modules/moduledeps" + "github.com/prebid/prebid-server/v4/modules/moduledeps" "github.com/stretchr/testify/assert" ) diff --git a/modules/prebid/rulesengine/result_functions.go b/modules/prebid/rulesengine/result_functions.go index 64fe23bc4a..eef632ba5b 100644 --- a/modules/prebid/rulesengine/result_functions.go +++ b/modules/prebid/rulesengine/result_functions.go @@ -5,10 +5,10 @@ import ( "errors" "fmt" - "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/rules" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/rules" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // ProcessedAuctionResultFunc is a type alias for a result function that runs in the processed auction request stage. diff --git a/modules/prebid/rulesengine/result_functions_test.go b/modules/prebid/rulesengine/result_functions_test.go index 1b78471ed1..d452f1d83d 100644 --- a/modules/prebid/rulesengine/result_functions_test.go +++ b/modules/prebid/rulesengine/result_functions_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - hs "github.com/prebid/prebid-server/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/rules" + hs "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/rules" "github.com/stretchr/testify/assert" ) diff --git a/modules/prebid/rulesengine/tree_builder.go b/modules/prebid/rulesengine/tree_builder.go index 438212f061..c74fc095cd 100644 --- a/modules/prebid/rulesengine/tree_builder.go +++ b/modules/prebid/rulesengine/tree_builder.go @@ -1,8 +1,8 @@ package rulesengine import ( - "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine/config" - "github.com/prebid/prebid-server/v3/rules" + "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine/config" + "github.com/prebid/prebid-server/v4/rules" ) // treeBuilder is a custom tree builder for the rules engine module. diff --git a/modules/prebid/rulesengine/tree_builder_test.go b/modules/prebid/rulesengine/tree_builder_test.go index 38fc6a9ae5..014c28db90 100644 --- a/modules/prebid/rulesengine/tree_builder_test.go +++ b/modules/prebid/rulesengine/tree_builder_test.go @@ -4,10 +4,10 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/rules" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/rules" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/modules/prebid/rulesengine/tree_manager.go b/modules/prebid/rulesengine/tree_manager.go index 35496e7591..6aca08c430 100644 --- a/modules/prebid/rulesengine/tree_manager.go +++ b/modules/prebid/rulesengine/tree_manager.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" - "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine/config" + "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine/config" "github.com/xeipuuv/gojsonschema" ) diff --git a/modules/prebid/rulesengine/tree_manager_test.go b/modules/prebid/rulesengine/tree_manager_test.go index b397074860..4fe7048c1a 100644 --- a/modules/prebid/rulesengine/tree_manager_test.go +++ b/modules/prebid/rulesengine/tree_manager_test.go @@ -8,7 +8,7 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/v3/modules/prebid/rulesengine/config" + "github.com/prebid/prebid-server/v4/modules/prebid/rulesengine/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/modules/prebid/rulesengine/tree_test.go b/modules/prebid/rulesengine/tree_test.go index 4769a2fc49..f7d4a318b1 100644 --- a/modules/prebid/rulesengine/tree_test.go +++ b/modules/prebid/rulesengine/tree_test.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - hs "github.com/prebid/prebid-server/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/rules" + hs "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/rules" "github.com/stretchr/testify/assert" ) diff --git a/modules/scientiamobile/wurfl_devicedetection/README.md b/modules/scientiamobile/wurfl_devicedetection/README.md new file mode 100644 index 0000000000..023b5828d2 --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/README.md @@ -0,0 +1,357 @@ +## WURFL Device Enrichment Module + +### Overview + +The **WURFL Device Enrichment Module** for Prebid Server enhances the OpenRTB 2.x payload +with comprehensive device detection data powered by **ScientiaMobile**’s WURFL device detection framework. +Thanks to WURFL's device database, the module provides accurate and comprehensive device-related information, +enabling bidders to make better-informed targeting and optimization decisions. + +### Key features + +#### Device Field Enrichment + +The WURFL module populates **missing or empty fields** in `ortb2.device` with the following data: + +- **make**: Manufacturer of the device (e.g., "Apple", "Samsung"). +- **model**: Device model (e.g., "iPhone 14", "Galaxy S22"). +- **os**: Operating system (e.g., "iOS", "Android"). +- **osv**: Operating system version (e.g., "16.0", "12.0"). +- **h**: Screen height in pixels. +- **w**: Screen width in pixels. +- **ppi**: Screen pixels per inch (PPI). +- **pxratio**: Screen pixel density ratio. +- **devicetype**: Device type (e.g., mobile, tablet, desktop). +- **js**: Support for JavaScript, where 0 = no, 1 = yes + +> **Note**: If these fields are already populated in the bid request, the module will not overwrite them. + +#### Publisher-Specific Enrichment + +Device enrichment is selectively enabled for publishers based on their **account ID**. +The module identifies publishers through the following fields: + +- `site.publisher.id` (for web environments). +- `app.publisher.id` (for mobile app environments). +- `dooh.publisher.id` (for digital out-of-home environments). + +### Build prerequisites + +To build the WURFL module, you need to install the WURFL Infuze from ScientiaMobile. +For more details, visit: [ScientiaMobile WURFL Infuze](https://docs.scientiamobile.com/documentation/infuze/infuze-c-api-user-guide). + +#### Note + +The WURFL module requires CGO at compile time to link against the WURFL Infuze library. + +To enable the WURFL module, the `wurfl` build tag must be specified: + +```go +go build -tags wurfl . +``` + +If the `wurfl` tag is not provided, the module will fail to initialize at startup. + +### Configuring the WURFL Module + +Below is a sample configuration for the WURFL module: + +```json +{ + "adapters": [ + { + "appnexus": { + "enabled": true + } + } + ], + "gdpr": { + "enabled": true, + "default_value": 0, + "timeouts_ms": { + "active_vendorlist_fetch": 900000 + } + }, + "hooks": { + "enabled": true, + "modules": { + "scientiamobile": { + "wurfl_devicedetection": { + "enabled": true, + "wurfl_file_path": "/path/to/wurfl.zip", + "wurfl_snapshot_url": "", + "wurfl_cache_size": 200000, + "allowed_publisher_ids": ["1","3"], + "ext_caps": true + } + } + }, + "host_execution_plan": { + "endpoints": { + "/openrtb2/auction": { + "stages": { + "entrypoint": { + "groups": [ + { + "timeout": 10, + "hook_sequence": [ + { + "module_code": "scientiamobile.wurfl_devicedetection", + "hook_impl_code": "scientiamobile-wurfl_devicedetection-entrypoint-hook" + } + ] + } + ] + }, + "raw_auction_request": { + "groups": [ + { + "timeout": 10, + "hook_sequence": [ + { + "module_code": "scientiamobile.wurfl_devicedetection", + "hook_impl_code": "scientiamobile-wurfl_devicedetection-raw-auction-request-hook" + } + ] + } + ] + } + } + } + } + } + } +} +``` + +The same configuration in YAML format + +```yaml +adapters: + - appnexus: + enabled: true +gdpr: + enabled: true + default_value: 0 + timeouts_ms: + active_vendorlist_fetch: 900000 +hooks: + enabled: true + modules: + scientiamobile: + wurfl_devicedetection: + enabled: true + wurfl_file_path: "/path/to/wurfl.zip" + wurfl_snapshot_url: "" + wurfl_cache_size: 200000 + allowed_publisher_ids: + - "1" + - "3" + ext_caps: true + host_execution_plan: + endpoints: + /openrtb2/auction: + stages: + entrypoint: + groups: + - timeout: 10 + hook_sequence: + - module_code: "scientiamobile.wurfl_devicedetection" + hook_impl_code: "scientiamobile-wurfl_devicedetection-entrypoint-hook" + raw_auction_request: + groups: + - timeout: 10 + hook_sequence: + - module_code: "scientiamobile.wurfl_devicedetection" + hook_impl_code: "scientiamobile-wurfl_devicedetection-raw-auction-request-hook" +``` + +### Configuration Options + +| Parameter | Requirement | Description | +|---------------------------|-------------|-------------------------------------------------------------------------------------------------------| +| **`wurfl_file_path`** | Mandatory | Path to the WURFL file (e.g. /path/to/wurfl.zip). | +| **`wurfl_snapshot_url`** | Optional | URL of the licensed WURFL snapshot. If set, it periodically updates the WURFL file in the `wurfl_file_path` directory, which must be writable. | +| **`wurfl_cache_size`** | Optional | Maximum number of devices stored in the WURFL cache. Defaults to the WURFL cache's standard size. | +| **`ext_caps`** | Optional | If `true`, the module adds all licensed capabilities to the `device.ext` object. | +| **`allowed_publisher_ids`** | Optional | List of publisher IDs permitted to use the module. Defaults to all publishers. | + +A valid WURFL license must include all the required capabilities for device enrichment. + +### Launching Prebid Server with the WURFL Module + +1. Download dependencies + +```bash +go mod download +``` + +2. Copy the sample [config file](modules/scientiamobile/wurfl_devicedetection/sample/pbs-example.json) + +```bash +cp modules/scientiamobile/wurfl_devicedetection/sample/pbs-example.json pbs.json +``` + +3. Copy the WURFL file to `wurfl_file_path` + +In order for the WURFL module to work, you need a WURFL file installed on your system. The WURFL Infuze package comes with a recent evaluation copy of the WURFL file called wurfl.zip. + +Commercial licensees of WURFL are granted access to "The Customer Vault", a personal virtual space containing purchased software licenses and weekly updated versions of the WURFL repository. + +For more details, visit: [ScientiaMobile WURFL Infuze](https://docs.scientiamobile.com/documentation/infuze/infuze-c-api-user-guide). + +4. Start the server + + ```bash + go run -tags wurfl . +``` + +When the server starts, it loads the WURFL file from `wurfl_file_path` into the module. +To enable automatic updates, ensure that `wurfl_snapshot_url` is correctly configured. + +Sample request data for testing is available in the module's `sample` directory. +Using the `auction` endpoint, you can observe WURFL-enriched device data in the response. + +### Sample Response + +Using the sample request data via `curl` when the module is configured with `ext_caps` set to `false` (or no value) + +```bash +curl http://localhost:8000/openrtb2/auction --data @modules/scientiamobile/wurfl_devicedetection/sample/request_data.json +``` + +the device object in the response will include WURFL device detection data: + +```json +"device": { + "ua": "Mozilla/5.0 (Linux; Android 15; Pixel 9 Pro XL Build/AP3A.241005.015;) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36 EdgA/124.0.2478.64", + "devicetype": 1, + "make": "Google", + "model": "Pixel 9 Pro XL", + "os": "Android", + "osv": "15", + "h": 2992, + "w": 1344, + "ppi": 481, + "pxratio": 2.55, + "js": 1, + "ext": { + "wurfl": { + "wurfl_id": "google_pixel_9_pro_xl_ver1_suban150" + } + } +} +``` + +When `ext_caps` is set to `true`, the response will include all licensed capabilities: + +```json +"device":{ + "ua":"Mozilla/5.0 (Linux; Android 15; Pixel 9 Pro XL Build/AP3A.241005.015; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36 EdgA/124.0.2478.64", + "devicetype":1, + "make":"Google", + "model":"Pixel 9 Pro XL", + "os":"Android", + "osv":"15", + "h":2992, + "w":1344, + "ppi":481, + "pxratio":2.55, + "js":1, + "ext":{ + "wurfl":{ + "wurfl_id":"google_pixel_9_pro_xl_ver1_suban150", + "mobile_browser_version":"", + "resolution_height":"2992", + "resolution_width":"1344", + "is_wireless_device":"true", + "is_tablet":"false", + "physical_form_factor":"phone_phablet", + "ajax_support_javascript":"true", + "preferred_markup":"html_web_4_0", + "brand_name":"Google", + "can_assign_phone_number":"true", + "xhtml_support_level":"4", + "ux_full_desktop":"false", + "device_os":"Android", + "physical_screen_width":"71", + "is_connected_tv":"false", + "is_smarttv":"false", + "physical_screen_height":"158", + "model_name":"Pixel 9 Pro XL", + "is_ott":"false", + "density_class":"2.55", + "marketing_name":"", + "device_os_version":"15.0", + "mobile_browser":"Chrome Mobile", + "pointing_method":"touchscreen", + "is_app_webview":"false", + "advertised_app_name":"Edge Browser", + "is_smartphone":"true", + "is_robot":"false", + "advertised_device_os":"Android", + "is_largescreen":"true", + "is_android":"true", + "is_xhtmlmp_preferred":"false", + "device_name":"Google Pixel 9 Pro XL", + "is_ios":"false", + "is_touchscreen":"true", + "is_wml_preferred":"false", + "is_app":"false", + "is_mobile":"true", + "is_phone":"true", + "is_full_desktop":"false", + "is_generic":"false", + "advertised_browser":"Edge", + "complete_device_name":"Google Pixel 9 Pro XL", + "advertised_browser_version":"124.0.2478.64", + "is_html_preferred":"true", + "is_windows_phone":"false", + "pixel_density":"481", + "form_factor":"Smartphone", + "advertised_device_os_version":"15" + } + } +} +``` + +### Building Docker images with WURFL support + +When building Prebid Server with the WURFL module using Docker, you need to install both compile-time and runtime WURFL dependencies. + +To build a Docker image with WURFL support: + +1. **Place the WURFL library package**: Copy the `libwurfl*.deb` package files into the `modules/scientiamobile/wurfl_devicedetection/libwurfl/` directory before building the Docker image. + +2. **Install compile-time dependencies**: In the build stage of your Dockerfile, before the `go build` command, add: + + ```dockerfile + # Installing WURFL compile-time dependencies if libwurfl package is present + RUN if ls modules/scientiamobile/wurfl_devicedetection/libwurfl/libwurfl*.deb 1> /dev/null 2>&1; then \ + dpkg -i modules/scientiamobile/wurfl_devicedetection/libwurfl/libwurfl*.deb; \ + fi + ``` + + And build with the WURFL tag: + + ```dockerfile + RUN go build -tags wurfl -mod=vendor -ldflags "-X github.com/prebid/prebid-server/v4/version.Ver=`git describe --tags | sed 's/^v//'` -X github.com/prebid/prebid-server/v4/version.Rev=`git rev-parse HEAD`" . + ``` + +3. **Install runtime dependencies**: In the runtime stage, add the WURFL runtime dependencies: + + ```dockerfile + # Installing WURFL runtime dependencies if libwurfl package is present + COPY modules/scientiamobile/wurfl_devicedetection/libwurfl/ /tmp/wurfl + RUN if ls /tmp/wurfl/libwurfl*.deb 1> /dev/null 2>&1; then \ + dpkg -i /tmp/wurfl/libwurfl*.deb; \ + apt-get update && \ + apt-get install -y curl && \ + apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*; \ + rm -rf /tmp/wurfl; \ + fi + ``` + +## Maintainer + + diff --git a/modules/scientiamobile/wurfl_devicedetection/config.go b/modules/scientiamobile/wurfl_devicedetection/config.go new file mode 100644 index 0000000000..8702e64365 --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/config.go @@ -0,0 +1,58 @@ +package wurfl_devicedetection + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +const ( + defaultCacheSize = "200000" +) + +var ErrWURFLFilePathRequired = errors.New("wurfl_file_path is required") + +// newConfig creates and validates a new config from the raw JSON data. +func newConfig(data json.RawMessage) (config, error) { + var cfg config + if err := jsonutil.UnmarshalValid(data, &cfg); err != nil { + return cfg, fmt.Errorf("failed to parse config: %s", err) + } + err := cfg.validate() + return cfg, err +} + +// config represents the configuration for the module. +type config struct { + // WURFLFilePath is the path to the WURFL file (i.e. /path/to/wurfl.zip). Required. + WURFLFilePath string `json:"wurfl_file_path"` + // WURFLSnapshotURL is the URL of the WURFL Snapshot. + // If set, it will be used to periodically update the WURFL file. + // The snapshot will be downloaded to the same directory as the WURFLFilePath. + // Make sure this directory is writable. + WURFLSnapshotURL string `json:"wurfl_snapshot_url"` + // WURFLCacheSize is the size of the WURFL Engine cache. Default is 200000 + WURFLCacheSize int `json:"wurfl_cache_size"` + // Holds the list of allowed publisher IDs. Leave empty to allow all. + AllowedPublisherIDs []string `json:"allowed_publisher_ids"` + // ExtCaps if true will include licensed WURFL capabilities in ortb2.Device.Ext + ExtCaps bool `json:"ext_caps"` +} + +// WURFLEngineCacheSize returns the cache size for the WURFL engine. +func (cfg config) WURFLEngineCacheSize() string { + if cfg.WURFLCacheSize > 0 { + return strconv.Itoa(cfg.WURFLCacheSize) + } + return defaultCacheSize +} + +func (cfg config) validate() error { + if cfg.WURFLFilePath == "" { + return ErrWURFLFilePathRequired + } + return nil +} diff --git a/modules/scientiamobile/wurfl_devicedetection/config_test.go b/modules/scientiamobile/wurfl_devicedetection/config_test.go new file mode 100644 index 0000000000..fba8845efb --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/config_test.go @@ -0,0 +1,121 @@ +package wurfl_devicedetection + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewConfig(t *testing.T) { + tests := []struct { + name string + input json.RawMessage + expectedErr bool + validate func(t *testing.T, cfg config) + }{ + { + name: "Valid config with default cache size", + input: json.RawMessage(`{ + "wurfl_snapshot_url": "http://example.com/wurfl-data", + "wurfl_file_path": "/tmp/wurfl.zip" + }`), + expectedErr: false, + validate: func(t *testing.T, cfg config) { + assert.Equal(t, "http://example.com/wurfl-data", cfg.WURFLSnapshotURL) + assert.Equal(t, "/tmp/wurfl.zip", cfg.WURFLFilePath) + assert.Equal(t, defaultCacheSize, cfg.WURFLEngineCacheSize()) + }, + }, + { + name: "Valid config with custom cache size", + input: json.RawMessage(`{ + "wurfl_snapshot_url": "http://example.com/wurfl-data", + "wurfl_file_path": "/tmp/wurfl.zip", + "wurfl_cache_size": 5000, + "wurfl_run_updater": true + }`), + expectedErr: false, + validate: func(t *testing.T, cfg config) { + assert.Equal(t, "5000", cfg.WURFLEngineCacheSize()) + }, + }, + { + name: "Invalid config - missing wurfl_snapshot_url", + input: json.RawMessage(`{ + "wurfl_file_path": "/tmp/wurfl" + }`), + expectedErr: false, + }, + { + name: "Invalid config - missing wurfl_file_path", + input: json.RawMessage(`{ + "wurfl_snapshot_url": "http://example.com/wurfl-data" + }`), + expectedErr: true, + }, + { + name: "Invalid config - malformed JSON", + input: json.RawMessage(`{ "wurfl_snapshot_url": "http://example.com/wurfl-data", "wurfl_file_path": "/tmp/wurfl",`), // Malformed JSON + expectedErr: true, + }, + { + name: "Empty config", + input: json.RawMessage(`{}`), + expectedErr: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + cfg, err := newConfig(tc.input) + + if tc.expectedErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + if tc.validate != nil { + tc.validate(t, cfg) + } + }) + } +} + +func TestValidate(t *testing.T) { + tests := []struct { + name string + cfg config + expectedErr bool + }{ + { + name: "Valid config", + cfg: config{ + WURFLSnapshotURL: "http://example.com/wurfl-data", + WURFLFilePath: "/tmp/wurfl.zip", + }, + expectedErr: false, + }, + { + name: "Invalid config - missing wurfl_file_path", + cfg: config{ + WURFLSnapshotURL: "http://example.com/wurfl-data", + }, + expectedErr: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + err := tc.cfg.validate() + + if tc.expectedErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + }) + } +} diff --git a/modules/scientiamobile/wurfl_devicedetection/libwurfl/.gitignore b/modules/scientiamobile/wurfl_devicedetection/libwurfl/.gitignore new file mode 100644 index 0000000000..a5baada18f --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/libwurfl/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore + diff --git a/modules/scientiamobile/wurfl_devicedetection/module.go b/modules/scientiamobile/wurfl_devicedetection/module.go new file mode 100644 index 0000000000..7cbf8d3a6d --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/module.go @@ -0,0 +1,185 @@ +package wurfl_devicedetection + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/buger/jsonparser" + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/hooks/hookexecution" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/modules/moduledeps" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/tidwall/sjson" +) + +const ( + wurflHeaderCtxKey = "wurfl_header" +) + +// declare conformity with hookstage.RawAuctionRequest interface +var ( + _ hookstage.RawAuctionRequest = Module{} + _ hookstage.Entrypoint = Module{} +) + +// payloadPublisherIDPaths specifies the possible paths in the Request payload JSON +// where the publisher ID can be defined. +var payloadPublisherIDPaths = [][]string{ + {"site", "publisher", "id"}, + {"app", "publisher", "id"}, + {"dooh", "publisher", "id"}, +} + +func Builder(configRaw json.RawMessage, _ moduledeps.ModuleDeps) (interface{}, error) { + cfg, err := newConfig(configRaw) + if err != nil { + return nil, err + } + + we, err := newWurflEngine(cfg) + if err != nil { + return nil, err + } + + m := Module{ + we: we, + extCaps: cfg.ExtCaps, + } + if len(cfg.AllowedPublisherIDs) > 0 { + m.allowedPublisherIDs = make(map[string]struct{}, len(cfg.AllowedPublisherIDs)) + for _, v := range cfg.AllowedPublisherIDs { + m.allowedPublisherIDs[v] = struct{}{} + } + } + return m, nil +} + +// Module must implement at least 1 hook interface. +type Module struct { + we wurflDeviceDetection + allowedPublisherIDs map[string]struct{} + extCaps bool +} + +// HandleEntrypointHook implements hookstage.Entrypoint. +func (m Module) HandleEntrypointHook(ctx context.Context, invocationCtx hookstage.ModuleInvocationContext, payload hookstage.EntrypointPayload) (hookstage.HookResult[hookstage.EntrypointPayload], error) { + result := hookstage.HookResult[hookstage.EntrypointPayload]{} + if !m.isPublisherAllowed(payload.Body) { + return result, hookexecution.NewFailure("publisher not allowed") + } + header := map[string]string{} + if payload.Request != nil { + for k := range payload.Request.Header { + header[k] = payload.Request.Header.Get(k) + } + } + moduleContext := hookstage.NewModuleContext() + moduleContext.Set(wurflHeaderCtxKey, header) + result.ModuleContext = moduleContext + + return result, nil +} + +// HandleRawAuctionHook implements hookstage.RawAuctionRequest. +func (m Module) HandleRawAuctionHook( + ctx context.Context, + invocationCtx hookstage.ModuleInvocationContext, + payload hookstage.RawAuctionRequestPayload, +) (hookstage.HookResult[hookstage.RawAuctionRequestPayload], error) { + result := hookstage.HookResult[hookstage.RawAuctionRequestPayload]{} + + if invocationCtx.ModuleContext == nil { + // The module context has not been initialized in the entrypoint hook. + // This could be due to a not allowed publisher or an error. + // Return the payload as is + return result, hookexecution.NewFailure("module context has not been initialized in the entrypoint hook") + } + + if isWURFLEnrichedRequest(payload) { + return result, nil + } + + headers, ok := invocationCtx.ModuleContext.Get(wurflHeaderCtxKey) + if !ok { + return result, hookexecution.NewFailure("invalid module context type") + } + rawHeaders, ok := headers.(map[string]string) + if !ok { + return result, hookexecution.NewFailure("invalid module context type") + } + result.ChangeSet.AddMutation(func(payload hookstage.RawAuctionRequestPayload) (hookstage.RawAuctionRequestPayload, error) { + ortb2Device, err := getOrtb2Device(payload) + if err != nil { + return payload, hookexecution.NewFailure("could not get ortb2.Device from payload %s", err) + } + + headers := makeHeaders(ortb2Device, rawHeaders) + + wd, err := m.we.DeviceDetection(headers) + if err != nil { + return payload, hookexecution.NewFailure("could not perform WURFL device detection %s", err) + } + + we := &wurflEnricher{ + WurflData: wd, + ExtCaps: m.extCaps, + } + we.EnrichDevice(&ortb2Device) + + updatedPayload, err := sjson.SetBytes(payload, "device", ortb2Device) + if err != nil { + return payload, hookexecution.NewFailure("could not update ortb2.Device payload %s", err) + } + return updatedPayload, nil + }, + hookstage.MutationUpdate, + "device", + ) + return result, nil +} + +// isPublisherAllowed verifies whether the publisher ID from a request payload is allowed to use this module. +// It checks against a list of authorized IDs, searching for the publisher ID in the site, app, or DOOH fields. +func (m Module) isPublisherAllowed(payload []byte) bool { + if m.allowedPublisherIDs == nil { + return true + } + var publisherID string + jsonparser.EachKey(payload, func(idx int, value []byte, vt jsonparser.ValueType, err error) { + if err != nil { + return + } + if vt != jsonparser.String { + return + } + publisherID = string(value) + }, payloadPublisherIDPaths...) + if publisherID == "" { + return false + } + _, found := m.allowedPublisherIDs[publisherID] + return found +} + +// getOrtb2Device extracts the openrtb2.Device from the bid request body. +func getOrtb2Device(payload []byte) (openrtb2.Device, error) { + device := openrtb2.Device{} + b, t, _, err := jsonparser.Get(payload, "device") + if err != nil { + return device, err + } + if t != jsonparser.Object { + return device, fmt.Errorf("expecting Object, got %s", t) + } + err = jsonutil.Unmarshal(b, &device) + return device, err +} + +// isWURFLEnrichedRequest returns true if the payload request has been already +// enriched with WURFL data like requests from Prebid.js with WURFL RTD module +func isWURFLEnrichedRequest(payload []byte) bool { + _, _, _, err := jsonparser.Get(payload, "device", "ext", ortb2WurflExtKey) + return err == nil +} diff --git a/modules/scientiamobile/wurfl_devicedetection/module_test.go b/modules/scientiamobile/wurfl_devicedetection/module_test.go new file mode 100644 index 0000000000..8dc0ee48ee --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/module_test.go @@ -0,0 +1,546 @@ +package wurfl_devicedetection + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/stretchr/testify/assert" +) + +func TestHandleEntrypointHook(t *testing.T) { + tests := []struct { + name string + module Module + payload hookstage.EntrypointPayload + expectedError bool + expectedModuleCtx map[string]map[string]string + }{ + { + name: "Publisher allowed with headers", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub1": {}}, + }, + payload: hookstage.EntrypointPayload{ + Body: []byte(`{"site":{"publisher":{"id":"pub1"}}}`), + Request: &http.Request{ + Header: http.Header{ + "User-Agent": {"Mozilla/5.0"}, + "X-Test": {"HeaderValue"}, + }, + }, + }, + expectedError: false, + expectedModuleCtx: map[string]map[string]string{ + wurflHeaderCtxKey: { + "User-Agent": "Mozilla/5.0", + "X-Test": "HeaderValue", + }, + }, + }, + { + name: "Publisher not allowed", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub1": {}}, + }, + payload: hookstage.EntrypointPayload{ + Body: []byte(`{"site":{"publisher":{"id":"pub2"}}}`), + Request: &http.Request{ + Header: http.Header{ + "User-Agent": {"Mozilla/5.0"}, + }, + }, + }, + expectedError: true, + expectedModuleCtx: nil, + }, + { + name: "No publisher ID in payload", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub1": {}}, + }, + payload: hookstage.EntrypointPayload{ + Body: []byte(`{}`), + Request: &http.Request{ + Header: http.Header{ + "User-Agent": {"Mozilla/5.0"}, + }, + }, + }, + expectedError: true, + expectedModuleCtx: nil, + }, + { + name: "Nil Request, publisher allowed", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub1": {}}, + }, + payload: hookstage.EntrypointPayload{ + Body: []byte(`{"site":{"publisher":{"id":"pub1"}}}`), + Request: nil, + }, + expectedError: false, + expectedModuleCtx: map[string]map[string]string{ + wurflHeaderCtxKey: {}, + }, + }, + { + name: "Nil allowedPublisherIDs (all publishers allowed)", + module: Module{ + allowedPublisherIDs: nil, + }, + payload: hookstage.EntrypointPayload{ + Body: []byte(`{"site":{"publisher":{"id":"pub1"}}}`), + Request: &http.Request{ + Header: http.Header{ + "X-Custom-Header": {"HeaderValue"}, + }, + }, + }, + expectedError: false, + expectedModuleCtx: map[string]map[string]string{ + wurflHeaderCtxKey: { + "X-Custom-Header": "HeaderValue", + }, + }, + }, + { + name: "Malformed payload", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub1": {}}, + }, + payload: hookstage.EntrypointPayload{ + Body: []byte(`{"site":{"publisher": `), + Request: &http.Request{ + Header: http.Header{ + "X-Custom-Header": {"HeaderValue"}, + }, + }, + }, + expectedError: true, + expectedModuleCtx: nil, + }, + { + name: "Empty headers", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub1": {}}, + }, + payload: hookstage.EntrypointPayload{ + Body: []byte(`{"site":{"publisher":{"id":"pub1"}}}`), + Request: &http.Request{Header: http.Header{}}, + }, + expectedError: false, + expectedModuleCtx: map[string]map[string]string{ + wurflHeaderCtxKey: {}, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + result, err := tc.module.HandleEntrypointHook(context.Background(), hookstage.ModuleInvocationContext{}, tc.payload) + + if tc.expectedError { + assert.Error(t, err) + assert.Nil(t, result.ModuleContext) + } else { + assert.NoError(t, err) + assert.NotNil(t, result.ModuleContext) + headers, _ := result.ModuleContext.Get(wurflHeaderCtxKey) + assert.Equal(t, tc.expectedModuleCtx[wurflHeaderCtxKey], headers) + } + }) + } +} + +func TestHandleRawAuctionHook(t *testing.T) { + tests := []struct { + name string + module Module + invocationCtx hookstage.ModuleInvocationContext + payload hookstage.RawAuctionRequestPayload + expectedErr bool + mutationErr bool + expectedPayload string + }{ + { + name: "Successful device enrichment without extCaps", + module: Module{ + we: &mockWurflDeviceDetection{ + detectDeviceFunc: func(headers map[string]string) (wurflData, error) { + return wurflData{ + "brand_name": "BrandX", + "model_name": "ModelY", + "is_mobile": "true", + "is_phone": "true", + "is_tablet": "false", + "form_factor": "Other Mobile", + }, nil + }, + }, + extCaps: false, + }, + invocationCtx: hookstage.ModuleInvocationContext{ + ModuleContext: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(wurflHeaderCtxKey, map[string]string{ + "User-Agent": "Mozilla/5.0", + }) + return ctx + }(), + }, + payload: []byte(`{"device":{"ua":"Mozilla/5.0"}}`), + expectedErr: false, + expectedPayload: `{ + "device": { + "ua": "Mozilla/5.0", + "make": "BrandX", + "model": "ModelY", + "hwv": "ModelY", + "devicetype": 1 + } + }`, + }, + { + name: "Nil module context", + module: Module{ + we: &mockWurflDeviceDetection{ + detectDeviceFunc: func(headers map[string]string) (wurflData, error) { + return wurflData{ + "brand_name": "BrandX", + "model_name": "ModelY", + "is_mobile": "true", + "is_phone": "true", + "is_tablet": "false", + "form_factor": "Other Mobile", + }, nil + }, + }, + extCaps: false, + }, + invocationCtx: hookstage.ModuleInvocationContext{}, + payload: []byte(`{"device":{"ua":"Mozilla/5.0"}}`), + expectedErr: true, + expectedPayload: `{"device":{"ua":"Mozilla/5.0"}}`, + }, + { + name: "Successful device enrichment with extCaps", + module: Module{ + we: &mockWurflDeviceDetection{ + detectDeviceFunc: func(headers map[string]string) (wurflData, error) { + return wurflData{ + "brand_name": "BrandX", + "model_name": "ModelY", + "is_mobile": "true", + "is_phone": "true", + "is_tablet": "false", + "form_factor": "Other Mobile", + }, nil + }, + }, + extCaps: true, + }, + invocationCtx: hookstage.ModuleInvocationContext{ + ModuleContext: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(wurflHeaderCtxKey, map[string]string{ + "User-Agent": "Mozilla/5.0", + }) + return ctx + }(), + }, + payload: []byte(`{"device":{"ua":"Mozilla/5.0"}}`), + expectedErr: false, + expectedPayload: `{ + "device": { + "ua": "Mozilla/5.0", + "make": "BrandX", + "model": "ModelY", + "hwv": "ModelY", + "devicetype": 1, + "ext": { + "wurfl": { + "brand_name": "BrandX", + "model_name": "ModelY", + "is_mobile": "true", + "is_phone": "true", + "is_tablet": "false", + "form_factor": "Other Mobile" + } + } + } + }`, + }, + { + name: "Successful device enrichment with ext data and with extCaps", + module: Module{ + we: &mockWurflDeviceDetection{ + detectDeviceFunc: func(headers map[string]string) (wurflData, error) { + return wurflData{ + "brand_name": "BrandX", + "model_name": "ModelY", + "is_mobile": "true", + "is_phone": "true", + "is_tablet": "false", + "form_factor": "Other Mobile", + }, nil + }, + }, + extCaps: true, + }, + invocationCtx: hookstage.ModuleInvocationContext{ + ModuleContext: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(wurflHeaderCtxKey, map[string]string{ + "User-Agent": "Mozilla/5.0", + }) + return ctx + }(), + }, + payload: []byte(`{"device":{"ua":"Mozilla/5.0", "ext": {"test": 1}}}`), + expectedErr: false, + expectedPayload: `{ + "device": { + "ua": "Mozilla/5.0", + "make": "BrandX", + "model": "ModelY", + "hwv": "ModelY", + "devicetype": 1, + "ext": { + "test": 1, + "wurfl": { + "brand_name": "BrandX", + "model_name": "ModelY", + "is_mobile": "true", + "is_phone": "true", + "is_tablet": "false", + "form_factor": "Other Mobile" + } + } + } + }`, + }, + { + name: "Failed device detection", + module: Module{ + we: &mockWurflDeviceDetection{ + detectDeviceFunc: func(headers map[string]string) (wurflData, error) { + return nil, errors.New("device detection error") + }, + }, + extCaps: false, + }, + invocationCtx: hookstage.ModuleInvocationContext{ + ModuleContext: func() *hookstage.ModuleContext { + ctx := hookstage.NewModuleContext() + ctx.Set(wurflHeaderCtxKey, map[string]string{ + "User-Agent": "Mozilla/5.0", + }) + return ctx + }(), + }, + payload: []byte(`{"device":{"ua":"Mozilla/5.0"}}`), + expectedErr: false, + mutationErr: true, + expectedPayload: `{"device":{"ua":"Mozilla/5.0"}}`, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + result, err := tc.module.HandleRawAuctionHook(context.Background(), tc.invocationCtx, tc.payload) + if tc.expectedErr { + assert.Error(t, err) + assert.JSONEq(t, tc.expectedPayload, string(tc.payload)) + return + } + 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] + // Apply mutation + mutatedPayload, err := mutation.Apply(tc.payload) + if tc.mutationErr { + assert.Error(t, err) + assert.JSONEq(t, tc.expectedPayload, string(tc.payload)) + return + } + assert.NoError(t, err) + + // Verify the mutated payload + assert.JSONEq(t, tc.expectedPayload, string(mutatedPayload)) + }) + } +} + +// Mock implementation of wurflDeviceDetection +type mockWurflDeviceDetection struct { + detectDeviceFunc func(headers map[string]string) (wurflData, error) +} + +func (m *mockWurflDeviceDetection) DeviceDetection(headers map[string]string) (wurflData, error) { + return m.detectDeviceFunc(headers) +} + +func TestIsPublisherAllowed(t *testing.T) { + tests := []struct { + name string + module Module + payload []byte + expected bool + allowedPublisherIDs map[string]bool + }{ + { + name: "Allowed publisher - site.publisher.id", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub1": {}}, + }, + payload: []byte(`{"site":{"publisher":{"id":"pub1"}}}`), + expected: true, + }, + { + name: "Disallowed publisher - site.publisher.id", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub1": {}}, + }, + payload: []byte(`{"site":{"publisher":{"id":"pub2"}}}`), + expected: false, + }, + { + name: "Allowed publisher - app.publisher.id", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub3": {}}, + }, + payload: []byte(`{"app":{"publisher":{"id":"pub3"}}}`), + expected: true, + }, + { + name: "Disallowed publisher - app.publisher.id", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub3": {}}, + }, + payload: []byte(`{"app":{"publisher":{"id":"pub4"}}}`), + expected: false, + }, + { + name: "Allowed publisher - dooh.publisher.id", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub5": {}}, + }, + payload: []byte(`{"dooh":{"publisher":{"id":"pub5"}}}`), + expected: true, + }, + { + name: "Disallowed publisher - dooh.publisher.id", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub5": {}}, + }, + payload: []byte(`{"dooh":{"publisher":{"id":"pub6"}}}`), + expected: false, + }, + { + name: "Empty payload - no publisher ID", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub1": {}}, + }, + payload: []byte(`{}`), + expected: false, + }, + { + name: "Nil allowedPublisherIDs - all publishers allowed", + module: Module{ + allowedPublisherIDs: nil, + }, + payload: []byte(`{"site":{"publisher":{"id":"pub1"}}}`), + expected: true, + }, + { + name: "Malformed JSON - no publisher ID", + module: Module{ + allowedPublisherIDs: map[string]struct{}{"pub1": {}}, + }, + payload: []byte(`{"site":{"publisher":{}}`), // Missing closing braces + expected: false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + result := tc.module.isPublisherAllowed(tc.payload) + assert.Equal(t, tc.expected, result) + }) + } +} + +func TestGetOrtb2Device(t *testing.T) { + tests := []struct { + name string + payload []byte + expectError bool + expected openrtb2.Device + }{ + { + name: "Valid device object", + payload: []byte(`{ + "device": { + "ua": "Mozilla/5.0", + "ip": "192.168.0.1", + "make": "Apple", + "model": "iPhone" + } + }`), + expectError: false, + expected: openrtb2.Device{ + UA: "Mozilla/5.0", + IP: "192.168.0.1", + Make: "Apple", + Model: "iPhone", + }, + }, + { + name: "Missing device field", + payload: []byte(`{}`), + expectError: true, + expected: openrtb2.Device{}, + }, + { + name: "Invalid device type (non-object)", + payload: []byte(`{"device": "string_instead_of_object"}`), + expectError: true, + expected: openrtb2.Device{}, + }, + { + name: "Malformed JSON", + payload: []byte(`{"device": { "ua": "Mozilla/5.0"`), // Missing closing braces + expectError: true, + expected: openrtb2.Device{}, + }, + { + name: "Empty payload", + payload: []byte(``), + expectError: true, + expected: openrtb2.Device{}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + device, err := getOrtb2Device(tc.payload) + + if tc.expectError { + assert.Error(t, err) + assert.Equal(t, tc.expected, device) + } else { + assert.NoError(t, err) + assert.Equal(t, tc.expected, device) + } + }) + } +} diff --git a/modules/scientiamobile/wurfl_devicedetection/module_wurfl_test.go b/modules/scientiamobile/wurfl_devicedetection/module_wurfl_test.go new file mode 100644 index 0000000000..e89784d52f --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/module_wurfl_test.go @@ -0,0 +1,59 @@ +//go:build wurfl + +package wurfl_devicedetection + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v4/modules/moduledeps" + "github.com/stretchr/testify/assert" +) + +func TestBuilder(t *testing.T) { + tests := []struct { + name string + configRaw json.RawMessage + expectedErr bool + validate func(t *testing.T, module interface{}) + }{ + { + name: "Valid configuration", + configRaw: json.RawMessage(`{ + "wurfl_snapshot_url": "http://example.com/wurfl-data", + "wurfl_file_path": "/tmp/wurfl.zip", + "allowed_publisher_ids": ["pub1", "pub2"], + "ext_caps": true + }`), + expectedErr: false, + validate: func(t *testing.T, module interface{}) { + m, ok := module.(Module) + assert.True(t, ok, "Module type assertion failed") + assert.Equal(t, map[string]struct{}{"pub1": {}, "pub2": {}}, m.allowedPublisherIDs) + assert.True(t, m.extCaps) + assert.NotNil(t, m.we) + }, + }, + { + name: "Invalid configuration - newConfig fails", + configRaw: json.RawMessage(`{ "wurfl_snapshot_url": "http://example.com/wurfl-data" }`), // Missing required fields + expectedErr: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + module, err := Builder(tc.configRaw, moduledeps.ModuleDeps{}) + + if tc.expectedErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + if tc.validate != nil { + tc.validate(t, module) + } + }) + } +} diff --git a/modules/scientiamobile/wurfl_devicedetection/sample/pbs_example.json b/modules/scientiamobile/wurfl_devicedetection/sample/pbs_example.json new file mode 100644 index 0000000000..2a0e7b60fc --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/sample/pbs_example.json @@ -0,0 +1,68 @@ +{ + "adapters": [ + { + "appnexus": { + "enabled": true + } + } + ], + "gdpr": { + "enabled": true, + "default_value": 0, + "timeouts_ms": { + "active_vendorlist_fetch": 900000 + } + }, + "hooks": { + "enabled": true, + "modules": { + "scientiamobile": { + "wurfl_devicedetection": { + "enabled": true, + "wurfl_file_path": "/path/to/wurfl.zip", + "wurfl_snapshot_url": "", + "wurfl_cache_size": 200000, + "allowed_publisher_ids": [ + "1", + "3" + ], + "ext_caps": true + } + } + }, + "host_execution_plan": { + "endpoints": { + "/openrtb2/auction": { + "stages": { + "entrypoint": { + "groups": [ + { + "timeout": 10, + "hook_sequence": [ + { + "module_code": "scientiamobile.wurfl_devicedetection", + "hook_impl_code": "scientiamobile-wurfl_devicedetection-entrypoint-hook" + } + ] + } + ] + }, + "raw_auction_request": { + "groups": [ + { + "timeout": 10, + "hook_sequence": [ + { + "module_code": "scientiamobile.wurfl_devicedetection", + "hook_impl_code": "scientiamobile-wurfl_devicedetection-raw-auction-request-hook" + } + ] + } + ] + } + } + } + } + } + } +} diff --git a/modules/scientiamobile/wurfl_devicedetection/sample/request_data.json b/modules/scientiamobile/wurfl_devicedetection/sample/request_data.json new file mode 100644 index 0000000000..42691bbc74 --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/sample/request_data.json @@ -0,0 +1,119 @@ +{ + "imp": [ + { + "ext": { + "data": { + "adserver": { + "name": "gam", + "adslot": "test" + }, + "pbadslot": "test", + "gpid": "test" + }, + "gpid": "test", + "prebid": { + "bidder": { + "appnexus": { + "placement_id": 1, + "use_pmt_rule": false + }, + "0test": { + "placement_id": 1 + } + }, + "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 15; Pixel 9 Pro XL Build/AP3A.241005.015; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36 EdgA/124.0.2478.64" + }, + "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": 1799310801804, + "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": 2000 +} diff --git a/modules/scientiamobile/wurfl_devicedetection/wurfl_data.go b/modules/scientiamobile/wurfl_devicedetection/wurfl_data.go new file mode 100644 index 0000000000..7cc1284407 --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/wurfl_data.go @@ -0,0 +1,86 @@ +package wurfl_devicedetection + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + + "github.com/prebid/prebid-server/v4/util/jsonutil" +) + +const ( + wurflID = "wurfl_id" +) + +var ErrWURFLIDNotExist = errors.New("WURFL ID does not exist") + +// declare conformity with json.Marshaler interface +var _ json.Marshaler = wurflData{} + +// wurflData represents the WURFL data +type wurflData map[string]string + +// Bool retrieves a capability value as a bool +func (wd wurflData) Bool(key string) (bool, error) { + val, exists := wd[key] + if !exists { + return false, fmt.Errorf("capability not found: %q", key) + } + result, err := strconv.ParseBool(val) + if err != nil { + return false, fmt.Errorf("could not parse %q to bool for capability %q", val, key) + } + return result, nil +} + +// Int64 retrieves a capability value as an int64 +func (wd wurflData) Int64(key string) (int64, error) { + val, exists := wd[key] + if !exists { + return 0, fmt.Errorf("capability not found: %q", key) + } + result, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return 0, fmt.Errorf("could not parse %q to int64 for capability %q", val, key) + } + return result, nil +} + +// Float64 retrieves a capability value as a float64 +func (wd wurflData) Float64(key string) (float64, error) { + val, exists := wd[key] + if !exists { + return 0.0, fmt.Errorf("capability not found: %q", key) + } + result, err := strconv.ParseFloat(val, 64) + if err != nil { + return 0.0, fmt.Errorf("could not parse %q to float64 for capability %q", val, key) + } + return result, nil +} + +// String retrieves a capability value as a string +func (wd wurflData) String(key string) (string, error) { + val, exists := wd[key] + if !exists { + return "", fmt.Errorf("capability not found: %q", key) + } + return val, nil +} + +// WurflIDToJSON returns a JSON representation of the WURFL ID +func (wd wurflData) WurflIDToJSON() ([]byte, error) { + m := make(map[string]string) + v, ok := wd[wurflID] + if !ok { + return nil, ErrWURFLIDNotExist + } + m[wurflID] = v + return jsonutil.Marshal(m) +} + +// MarshalJSON customizes the JSON marshaling for wurflData +func (wd wurflData) MarshalJSON() ([]byte, error) { + return jsonutil.Marshal(map[string]string(wd)) +} diff --git a/modules/scientiamobile/wurfl_devicedetection/wurfl_data_test.go b/modules/scientiamobile/wurfl_devicedetection/wurfl_data_test.go new file mode 100644 index 0000000000..257d5933d9 --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/wurfl_data_test.go @@ -0,0 +1,145 @@ +package wurfl_devicedetection + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestWurflData_MarshalJSON(t *testing.T) { + tests := []struct { + name string + data wurflData + expected string + }{ + { + name: "Non-empty wurflData", + data: wurflData{ + "brand_name": "BrandX", + "model_name": "ModelY", + }, + expected: `{"brand_name":"BrandX","model_name":"ModelY"}`, + }, + { + name: "Empty wurflData", + data: wurflData{}, + expected: `{}`, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + result, err := tc.data.MarshalJSON() + assert.NoError(t, err) + assert.JSONEq(t, tc.expected, string(result)) + }) + } +} + +func TestWurflData_SON(t *testing.T) { + tests := []struct { + name string + data wurflData + expected string + expectedErr bool + }{ + { + name: "Non-empty wurflData", + data: wurflData{ + "brand_name": "BrandX", + "model_name": "ModelY", + "wurfl_id": "test", + }, + expected: `{"wurfl_id":"test"}`, + }, + { + name: "Missed WURFL ID", + data: wurflData{}, + expectedErr: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + result, err := tc.data.WurflIDToJSON() + if tc.expectedErr { + assert.Error(t, err) + assert.Nil(t, result) + return + } + assert.NoError(t, err) + assert.JSONEq(t, tc.expected, string(result)) + }) + } +} + +func TestWurflData_Bool(t *testing.T) { + data := wurflData{ + "ajax_support_javascript": "true", + "invalid_value": "not_a_bool", + } + + v, err := data.Bool("ajax_support_javascript") + assert.NoError(t, err) + assert.True(t, v) + + v, err = data.Bool("invalid_value") + assert.Error(t, err) + assert.Empty(t, v) + + v, err = data.Bool("non_existent_key") + assert.Error(t, err) + assert.Empty(t, v) +} + +func TestWurflData_Float64(t *testing.T) { + data := wurflData{ + "density_class": "2.5", + "invalid_value": "not_a_number", + } + + v, err := data.Float64("density_class") + assert.NoError(t, err) + assert.Equal(t, 2.5, v) + + v, err = data.Float64("invalid_value") + assert.Empty(t, v) + assert.Error(t, err) + + v, err = data.Float64("non_existent_key") + assert.Empty(t, v) + assert.Error(t, err) +} + +func TestWurflData_Int64(t *testing.T) { + data := wurflData{ + "resolution_height": "1080", + "invalid_value": "not_a_number", + } + + v, err := data.Int64("resolution_height") + assert.NoError(t, err) + assert.Equal(t, int64(1080), v) + + v, err = data.Int64("invalid_value") + assert.Empty(t, v) + assert.Error(t, err) + + v, err = data.Int64("non_existent_key") + assert.Empty(t, v) + assert.Error(t, err) +} + +func TestWurflData_String(t *testing.T) { + data := wurflData{ + "brand_name": "BrandX", + } + + v, err := data.String("brand_name") + assert.NoError(t, err) + assert.Equal(t, "BrandX", v) + + v, err = data.String("non_existent_key") + assert.Empty(t, v) + assert.Error(t, err) +} diff --git a/modules/scientiamobile/wurfl_devicedetection/wurfl_engine.go b/modules/scientiamobile/wurfl_devicedetection/wurfl_engine.go new file mode 100644 index 0000000000..ebcad9c607 --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/wurfl_engine.go @@ -0,0 +1,145 @@ +//go:build wurfl + +package wurfl_devicedetection + +import ( + "fmt" + "strings" + + wurfl "github.com/WURFL/golang-wurfl" + "github.com/golang/glog" +) + +// declare conformity with wurflDeviceDetection interface +var _ wurflDeviceDetection = (*wurflEngine)(nil) + +// vcaps is the list of WURFL virtual capabilities to request +var vcaps = []string{ + advertisedDeviceOSCapKey, + advertisedDeviceOSVersionCapKey, + completeDeviceNameCapKey, + isFullDesktopCapKey, + isMobileCapKey, + isPhoneCapKey, + formFactorCapKey, + pixelDensityCapKey, +} + +// newWurflEngine creates a new Enricher +func newWurflEngine(c config) (wurflDeviceDetection, error) { + wengine, err := wurfl.Create(c.WURFLFilePath, + nil, + nil, + -1, + wurfl.WurflCacheProviderLru, + c.WURFLEngineCacheSize(), + ) + if err != nil { + return nil, err + } + + caps := wengine.GetAllCaps() + e := &wurflEngine{ + wengine: wengine, + caps: caps, + vcaps: vcaps, + } + + err = e.validate() + if err != nil { + return nil, err + } + + e.startUpdater(c.WURFLSnapshotURL) + + return e, nil +} + +// wurflEngine is the ortb2 enricher powered by WURFL +type wurflEngine struct { + wengine *wurfl.Wurfl + caps []string + vcaps []string +} + +// deviceDetection performs device detection using the WURFL engine. +func (e *wurflEngine) DeviceDetection(headers map[string]string) (wurflData, error) { + wurflDevice, err := e.wengine.LookupWithImportantHeaderMap(headers) + if err != nil { + return nil, err + } + defer wurflDevice.Destroy() + + wurflDeviceID, err := wurflDevice.GetDeviceID() + if err != nil { + return nil, err + } + wurflData, err := wurflDevice.GetStaticCaps(e.caps) + if err != nil { + return nil, err + } + vcaps, err := wurflDevice.GetVirtualCaps(e.vcaps) + if err != nil { + return nil, err + } + for k, v := range vcaps { + wurflData[k] = v + } + wurflData[wurflID] = wurflDeviceID + return wurflData, nil +} + +func (e *wurflEngine) startUpdater(snapshotURL string) { + if snapshotURL == "" { + return + } + + err := e.wengine.SetUpdaterDataURL(snapshotURL) + if err != nil { + glog.Errorf("could not set WURFL Updater Snapshot URL: %s", err.Error()) + return + } + + err = e.wengine.SetUpdaterDataFrequency(wurfl.WurflUpdaterFrequencyDaily) + if err != nil { + glog.Errorf("could not set the WURFL Updater frequency: %s", err.Error()) + return + } + + err = e.wengine.UpdaterStart() + if err != nil { + glog.Errorf("could not start the WURFL Updater: %s", err.Error()) + return + } +} + +// validate checks if the WURFL file has all the required capabilities +func (e *wurflEngine) validate() error { + requiredCaps := []string{ + ajaxSupportJavascriptCapKey, + brandNameCapKey, + densityClassCapKey, + isConnectedTVCapKey, + isConsoleCapKey, + isOTTCapKey, + isTabletCapKey, + modelNameCapKey, + physicalFormFactorCapKey, + resolutionHeightCapKey, + resolutionWidthCapKey, + } + m := map[string]struct{}{} + for _, val := range e.caps { + m[val] = struct{}{} + } + missed := []string{} + for _, val := range requiredCaps { + if _, ok := m[val]; !ok { + missed = append(missed, val) + } + } + if len(missed) > 0 { + return fmt.Errorf("WURFL file is missing the following capabilities: %s", strings.Join(missed, ",")) + } + return nil +} diff --git a/modules/scientiamobile/wurfl_devicedetection/wurfl_engine_fallback.go b/modules/scientiamobile/wurfl_devicedetection/wurfl_engine_fallback.go new file mode 100644 index 0000000000..8c83b9f89e --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/wurfl_engine_fallback.go @@ -0,0 +1,11 @@ +//go:build !wurfl + +package wurfl_devicedetection + +import "errors" + +const wurflBuildTagMissingError = "wurfl module requires the wurfl build tag; build with: go build -tags wurfl" + +func newWurflEngine(_ config) (wurflDeviceDetection, error) { + return nil, errors.New(wurflBuildTagMissingError) +} diff --git a/modules/scientiamobile/wurfl_devicedetection/wurfl_engine_fallback_test.go b/modules/scientiamobile/wurfl_devicedetection/wurfl_engine_fallback_test.go new file mode 100644 index 0000000000..de0334fe19 --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/wurfl_engine_fallback_test.go @@ -0,0 +1,14 @@ +//go:build !wurfl + +package wurfl_devicedetection + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewWurflEngineFallbackError(t *testing.T) { + _, err := newWurflEngine(config{}) + assert.EqualError(t, err, wurflBuildTagMissingError) +} diff --git a/modules/scientiamobile/wurfl_devicedetection/wurfl_enricher.go b/modules/scientiamobile/wurfl_devicedetection/wurfl_enricher.go new file mode 100644 index 0000000000..a7753bac35 --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/wurfl_enricher.go @@ -0,0 +1,194 @@ +package wurfl_devicedetection + +import ( + "github.com/golang/glog" + "github.com/prebid/openrtb/v20/adcom1" + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/tidwall/sjson" +) + +const ( + advertisedDeviceOSCapKey = "advertised_device_os" + advertisedDeviceOSVersionCapKey = "advertised_device_os_version" + ajaxSupportJavascriptCapKey = "ajax_support_javascript" + brandNameCapKey = "brand_name" + completeDeviceNameCapKey = "complete_device_name" + densityClassCapKey = "density_class" + formFactorCapKey = "form_factor" + isConsoleCapKey = "is_console" + isConnectedTVCapKey = "is_connected_tv" + isFullDesktopCapKey = "is_full_desktop" + isMobileCapKey = "is_mobile" + isOTTCapKey = "is_ott" + isPhoneCapKey = "is_phone" + isTabletCapKey = "is_tablet" + modelNameCapKey = "model_name" + physicalFormFactorCapKey = "physical_form_factor" + pixelDensityCapKey = "pixel_density" + resolutionHeightCapKey = "resolution_height" + resolutionWidthCapKey = "resolution_width" +) + +const ( + ortb2WurflExtKey = "wurfl" +) + +const ( + outOfHomeDevice = "out_of_home_device" +) + +// WURFL form_factor values +const ( + formFactorDesktop = "Desktop" + formFactorSmartphone = "Smartphone" + formFactorFeaturePhone = "Feature Phone" + formFactorTablet = "Tablet" + formFactorSmartTV = "Smart-TV" + formFactorOtherNonMobile = "Other Non-Mobile" + formFactorOtherMobile = "Other Mobile" +) + +// wurflDeviceDetection wraps the methods for the WURFL device detection +type wurflDeviceDetection interface { + DeviceDetection(headers map[string]string) (wurflData, error) +} + +// wurflEnricher represents the WURFL Enricher for Prebid +type wurflEnricher struct { + // WurflData holds the WURFL data + WurflData wurflData + // extCaps if true will enrich the device.ext field with all WURFL caps + // Default to enrich only with the wurfl_id + ExtCaps bool +} + +// EnrichDevice enriches OpenRTB 2.x device with WURFL data +func (we *wurflEnricher) EnrichDevice(device *openrtb2.Device) { + wd := we.WurflData + if device.Make == "" { + if v, err := wd.String(brandNameCapKey); err == nil { + device.Make = v + } + } + if device.Model == "" { + if v, err := wd.String(modelNameCapKey); err == nil { + device.Model = v + } + } + if device.DeviceType == 0 { + device.DeviceType = we.makeDeviceType() + } + if device.OS == "" { + if v, err := wd.String(advertisedDeviceOSCapKey); err == nil { + device.OS = v + } + } + if device.OSV == "" { + if v, err := wd.String(advertisedDeviceOSVersionCapKey); err == nil { + device.OSV = v + } + } + if device.HWV == "" { + if v, err := wd.String(modelNameCapKey); err == nil { + device.HWV = v + } + } + if device.H == 0 { + if v, err := wd.Int64(resolutionHeightCapKey); err == nil { + device.H = v + } + } + if device.W == 0 { + if v, err := wd.Int64(resolutionWidthCapKey); err == nil { + device.W = v + } + } + if device.PPI == 0 { + if v, err := wd.Int64(pixelDensityCapKey); err == nil { + device.PPI = v + } + } + if device.PxRatio == 0 { + if v, err := wd.Float64(densityClassCapKey); err == nil { + device.PxRatio = v + } + } + if device.JS == nil { + if v, err := wd.Bool(ajaxSupportJavascriptCapKey); err == nil { + var js int8 + if v { + js = 1 + } + device.JS = &js + } + } + + wurflExtData, err := we.wurflExtData() + if err != nil { + glog.Warningf("could not create WURFL ext data: %s", err) + return + } + // merges the WURFL data in device.ext under the wurfl "namespace" + ext, err := sjson.SetRawBytes(device.Ext, ortb2WurflExtKey, wurflExtData) + if err != nil { + glog.Warningf("could not set WURFL ext data: %s", err) + return + } + device.Ext = ext +} + +// wurflExtData returns the WURFL data in JSON format for the device.ext field +func (we *wurflEnricher) wurflExtData() ([]byte, error) { + if we.ExtCaps { + // return all WURFL data + return we.WurflData.MarshalJSON() + } + // return only the WURFL ID + return we.WurflData.WurflIDToJSON() +} + +// makeDeviceType returns an OpenRTB2 DeviceType from WURFL data +// see https://www.scientiamobile.com/how-to-populate-iab-openrtb-device-object/ +func (we *wurflEnricher) makeDeviceType() adcom1.DeviceType { + wd := we.WurflData + unknownDeviceType := adcom1.DeviceType(0) + + // Priority 1: Check is_ott + if isOTT, err := wd.Bool(isOTTCapKey); err == nil && isOTT { + return adcom1.DeviceSetTopBox + } + + // Priority 2: Check is_console + if isConsole, err := wd.Bool(isConsoleCapKey); err == nil && isConsole { + return adcom1.DeviceConnected + } + + // Priority 3: Check physical_form_factor for out_of_home_device + if physicalFormFactor, err := wd.String(physicalFormFactorCapKey); err == nil && physicalFormFactor == outOfHomeDevice { + return adcom1.DeviceOOH + } + + // Priority 4: Check if form_factor exists and switch on its value + formFactor, err := wd.String(formFactorCapKey) + if err != nil { + // form_factor not available, return unknown + return unknownDeviceType + } + + switch formFactor { + case formFactorDesktop: + return adcom1.DevicePC + case formFactorSmartphone, formFactorFeaturePhone: + return adcom1.DevicePhone + case formFactorTablet: + return adcom1.DeviceTablet + case formFactorSmartTV: + return adcom1.DeviceTV + case formFactorOtherNonMobile: + return adcom1.DeviceConnected + case formFactorOtherMobile: + return adcom1.DeviceMobile + default: + return unknownDeviceType + } +} diff --git a/modules/scientiamobile/wurfl_devicedetection/wurfl_enricher_test.go b/modules/scientiamobile/wurfl_devicedetection/wurfl_enricher_test.go new file mode 100644 index 0000000000..5c34017232 --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/wurfl_enricher_test.go @@ -0,0 +1,213 @@ +package wurfl_devicedetection + +import ( + "encoding/json" + "testing" + + "github.com/prebid/openrtb/v20/adcom1" + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/stretchr/testify/assert" +) + +func TestWurflEnricher_EnrichDevice(t *testing.T) { + data := wurflData{ + "brand_name": "BrandX", + "model_name": "ModelY", + "advertised_device_os": "Android", + "resolution_height": "1080", + "resolution_width": "1920", + "pixel_density": "300", + "density_class": "2.5", + "ajax_support_javascript": "true", + "is_mobile": "true", + "is_phone": "true", + "is_tablet": "false", + } + + device := &openrtb2.Device{} + + we := &wurflEnricher{ + WurflData: data, + } + we.EnrichDevice(device) + + assert.Equal(t, "BrandX", device.Make) + assert.Equal(t, "ModelY", device.Model) + assert.Equal(t, "Android", device.OS) + assert.Equal(t, int64(1080), device.H) + assert.Equal(t, int64(1920), device.W) + assert.Equal(t, int64(300), device.PPI) + assert.Equal(t, 2.5, device.PxRatio) + assert.NotNil(t, device.JS) + assert.Equal(t, int8(1), *device.JS) + assert.Nil(t, device.Ext) +} + +func TestWurflEnricher_EnrichDeviceExt(t *testing.T) { + tests := []struct { + name string + wurflData wurflData + initialExt json.RawMessage + expectedExt string + expectNoError bool + }{ + { + name: "Add wurfl data to empty device ext", + wurflData: wurflData{ + "brand_name": "BrandX", + "model_name": "ModelY", + }, + initialExt: nil, + expectedExt: `{"wurfl":{"brand_name":"BrandX","model_name":"ModelY"}}`, + expectNoError: true, + }, + { + name: "Merge wurfl data into existing device ext", + wurflData: wurflData{ + "brand_name": "BrandZ", + }, + initialExt: json.RawMessage(`{"existing_key":"existing_value"}`), + expectedExt: `{"existing_key":"existing_value","wurfl":{"brand_name":"BrandZ"}}`, + expectNoError: true, + }, + { + name: "Invalid initial ext JSON", + wurflData: wurflData{ + "brand_name": "BrandX", + }, + initialExt: json.RawMessage(`{"invalid_json":`), // Malformed JSON + expectedExt: `{"invalid_json":`, // Should remain as is + expectNoError: false, + }, + { + name: "Empty wurfl data", + wurflData: wurflData{}, + initialExt: nil, + expectedExt: `{"wurfl":{}}`, + expectNoError: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + device := &openrtb2.Device{Ext: tc.initialExt} + + we := &wurflEnricher{ + WurflData: tc.wurflData, + ExtCaps: true, + } + // Call the method being tested + we.EnrichDevice(device) + + // Assert the results + if tc.expectNoError { + assert.JSONEq(t, tc.expectedExt, string(device.Ext)) + } else { + assert.NotEqual(t, tc.expectedExt, string(device.Ext)) + } + }) + } +} + +func TestWurflEnricher_MakeDeviceType(t *testing.T) { + tests := []struct { + name string + data wurflData + expected adcom1.DeviceType + }{ + { + name: "Mobile device - form_factor Other Mobile", + data: wurflData{ + "form_factor": "Other Mobile", + }, + expected: adcom1.DeviceMobile, + }, + { + name: "Smartphone device - form_factor Smartphone", + data: wurflData{ + "form_factor": "Smartphone", + }, + expected: adcom1.DevicePhone, + }, + { + name: "Feature Phone device - form_factor Feature Phone", + data: wurflData{ + "form_factor": "Feature Phone", + }, + expected: adcom1.DevicePhone, + }, + { + name: "Connected TV - form_factor Smart-TV", + data: wurflData{ + "form_factor": "Smart-TV", + }, + expected: adcom1.DeviceTV, + }, + { + name: "Full desktop - form_factor Desktop", + data: wurflData{ + "form_factor": "Desktop", + }, + expected: adcom1.DevicePC, + }, + { + name: "Tablet device - form_factor Tablet", + data: wurflData{ + "form_factor": "Tablet", + }, + expected: adcom1.DeviceTablet, + }, + { + name: "Connected device - form_factor Other Non-Mobile", + data: wurflData{ + "form_factor": "Other Non-Mobile", + }, + expected: adcom1.DeviceConnected, + }, + { + name: "Set-top box (OTT) - is_ott has priority", + data: wurflData{ + "is_ott": "true", + "form_factor": "Desktop", + }, + expected: adcom1.DeviceSetTopBox, + }, + { + name: "Console device - is_console has priority", + data: wurflData{ + "is_console": "true", + "form_factor": "Desktop", + }, + expected: adcom1.DeviceConnected, + }, + { + name: "Out-of-home device - physical_form_factor has priority", + data: wurflData{ + "physical_form_factor": "out_of_home_device", + "form_factor": "Desktop", + }, + expected: adcom1.DeviceOOH, + }, + { + name: "Unknown device type - no form_factor", + data: wurflData{}, + expected: adcom1.DeviceType(0), + }, + { + name: "Unknown device type - invalid form_factor", + data: wurflData{ + "form_factor": "Unknown", + }, + expected: adcom1.DeviceType(0), + }, + } + + for _, tc := range tests { + we := &wurflEnricher{ + WurflData: tc.data, + } + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.expected, we.makeDeviceType()) + }) + } +} diff --git a/modules/scientiamobile/wurfl_devicedetection/wurfl_headers.go b/modules/scientiamobile/wurfl_devicedetection/wurfl_headers.go new file mode 100644 index 0000000000..163102b414 --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/wurfl_headers.go @@ -0,0 +1,104 @@ +package wurfl_devicedetection + +import ( + "fmt" + "strings" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v4/util/iterutil" +) + +const ( + secCHUA = "Sec-CH-UA" + secCHUAPlatform = "Sec-CH-UA-Platform" + secCHUAPlatformVersion = "Sec-CH-UA-Platform-Version" + secCHUAMobile = "Sec-CH-UA-Mobile" + secCHUAArch = "Sec-CH-UA-Arch" + secCHUAModel = "Sec-CH-UA-Model" + secCHUAFullVersionList = "Sec-CH-UA-Full-Version-List" + userAgent = "User-Agent" +) + +// clientHintEscaper escapes special characters in Client Hint header values per RFC 9651. +// Only backslash and double-quote need escaping. Backslash must be escaped first. +var clientHintEscaper = strings.NewReplacer( + `\`, `\\`, // Must escape backslash FIRST + `"`, `\"`, // Then escape quotes +) + +func makeHeaders(ortb2Device openrtb2.Device, rawHeaders map[string]string) map[string]string { + sua := ortb2Device.SUA + ua := ortb2Device.UA + if ua == "" { + if sua == nil { + return rawHeaders + } + if sua.Browsers == nil { + return rawHeaders + } + } + headers := make(map[string]string) + + if ua != "" { + headers[userAgent] = ua + } + + if sua == nil { + return headers + } + + if sua.Browsers == nil { + return headers + } + + brandList := makeBrandList(sua.Browsers) + headers[secCHUA] = brandList + headers[secCHUAFullVersionList] = brandList + + if sua.Platform != nil { + headers[secCHUAPlatform] = quoteAndEscapeClientHintField(sua.Platform.Brand) + headers[secCHUAPlatformVersion] = quoteAndEscapeClientHintField(strings.Join(sua.Platform.Version, ".")) + } + + if sua.Model != "" { + headers[secCHUAModel] = quoteAndEscapeClientHintField(sua.Model) + } + + if sua.Architecture != "" { + headers[secCHUAArch] = quoteAndEscapeClientHintField(sua.Architecture) + } + + if sua.Mobile != nil { + headers[secCHUAMobile] = fmt.Sprintf("?%d", *sua.Mobile) + } + + return headers +} + +func makeBrandList(brandVersions []openrtb2.BrandVersion) string { + var builder strings.Builder + first := true + for version := range iterutil.SlicePointerValues(brandVersions) { + if version.Brand == "" { + continue + } + if !first { + builder.WriteString(", ") + } + first = false + + brandName := quoteAndEscapeClientHintField(version.Brand) + builder.WriteString(brandName) + builder.WriteString(`;v="`) + builder.WriteString(clientHintEscaper.Replace(strings.Join(version.Version, "."))) + builder.WriteString(`"`) + } + return builder.String() +} + +// quoteAndEscapeClientHintField escapes special characters per RFC 9651 and wraps +// the value in double quotes for use in HTTP Client Hint header values. +// Backslashes and double-quotes are escaped as required by the structured field specification. +func quoteAndEscapeClientHintField(value string) string { + return `"` + clientHintEscaper.Replace(value) + `"` +} diff --git a/modules/scientiamobile/wurfl_devicedetection/wurfl_headers_test.go b/modules/scientiamobile/wurfl_devicedetection/wurfl_headers_test.go new file mode 100644 index 0000000000..36456954ff --- /dev/null +++ b/modules/scientiamobile/wurfl_devicedetection/wurfl_headers_test.go @@ -0,0 +1,171 @@ +package wurfl_devicedetection + +import ( + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/stretchr/testify/assert" +) + +func TestMakeHeaders(t *testing.T) { + tests := []struct { + name string + device openrtb2.Device + rawHeaders map[string]string + expected map[string]string + }{ + { + name: "No SUA and no UA", + device: openrtb2.Device{}, + rawHeaders: map[string]string{"Custom-Header": "Value"}, + expected: map[string]string{"Custom-Header": "Value"}, + }, + { + name: "Only UA", + device: openrtb2.Device{ + UA: "Mozilla/5.0", + }, + rawHeaders: map[string]string{}, + expected: map[string]string{"User-Agent": "Mozilla/5.0"}, + }, + { + name: "UA and SUA without Browsers", + device: openrtb2.Device{ + UA: "Mozilla/5.0", + SUA: &openrtb2.UserAgent{ + Platform: &openrtb2.BrandVersion{ + Brand: "Android", + Version: []string{"12"}, + }, + }, + }, + rawHeaders: map[string]string{}, + expected: map[string]string{"User-Agent": "Mozilla/5.0"}, + }, + { + name: "No UA and SUA without Browsers", + device: openrtb2.Device{ + SUA: &openrtb2.UserAgent{ + Platform: &openrtb2.BrandVersion{ + Brand: "Android", + Version: []string{"12"}, + }, + }, + }, + rawHeaders: map[string]string{"User-Agent": "Mozilla/5.0"}, + expected: map[string]string{"User-Agent": "Mozilla/5.0"}, + }, + { + name: "SUA with browsers and platform", + device: openrtb2.Device{ + SUA: &openrtb2.UserAgent{ + Browsers: []openrtb2.BrandVersion{ + {Brand: "Google Chrome", Version: []string{"114", "0", "5735"}}, + }, + Platform: &openrtb2.BrandVersion{ + Brand: "Android", + Version: []string{"12"}, + }, + }, + }, + rawHeaders: map[string]string{}, + expected: map[string]string{ + "Sec-CH-UA": `"Google Chrome";v="114.0.5735"`, + "Sec-CH-UA-Full-Version-List": `"Google Chrome";v="114.0.5735"`, + "Sec-CH-UA-Platform": `"Android"`, + "Sec-CH-UA-Platform-Version": `"12"`, + }, + }, + { + name: "SUA with mobile and model", + device: openrtb2.Device{ + SUA: &openrtb2.UserAgent{ + Browsers: []openrtb2.BrandVersion{ + {Brand: "Google Chrome", Version: []string{"114", "0", "5735"}}, + }, + Mobile: func(i int8) *int8 { return &i }(1), + Model: "Pixel 6", + }, + }, + rawHeaders: map[string]string{}, + expected: map[string]string{ + "Sec-CH-UA": `"Google Chrome";v="114.0.5735"`, + "Sec-CH-UA-Full-Version-List": `"Google Chrome";v="114.0.5735"`, + "Sec-CH-UA-Mobile": `?1`, + "Sec-CH-UA-Model": `"Pixel 6"`, + }, + }, + { + name: "SUA with multiple browsers brand", + device: openrtb2.Device{ + SUA: &openrtb2.UserAgent{ + Browsers: []openrtb2.BrandVersion{ + {Brand: "Chromium", Version: []string{"114"}}, + {Brand: "Google Chrome", Version: []string{"114", "0", "5735"}}, + {Brand: " Not A;Brand", Version: []string{"99"}}, + }, + Platform: &openrtb2.BrandVersion{ + Brand: "Windows", + Version: []string{"10", "0", "0"}, + }, + }, + }, + rawHeaders: map[string]string{}, + expected: map[string]string{ + "Sec-CH-UA": `"Chromium";v="114", "Google Chrome";v="114.0.5735", " Not A;Brand";v="99"`, + "Sec-CH-UA-Full-Version-List": `"Chromium";v="114", "Google Chrome";v="114.0.5735", " Not A;Brand";v="99"`, + "Sec-CH-UA-Platform": `"Windows"`, + "Sec-CH-UA-Platform-Version": `"10.0.0"`, + }, + }, + { + name: "SUA with special characters in version strings (RFC 9651)", + device: openrtb2.Device{ + SUA: &openrtb2.UserAgent{ + Browsers: []openrtb2.BrandVersion{ + {Brand: "Chrome", Version: []string{`1", "Injected";v="99`}}, + {Brand: "Brand", Version: []string{`1\2`}}, + }, + }, + }, + rawHeaders: map[string]string{}, + expected: map[string]string{ + "Sec-CH-UA": `"Chrome";v="1\", \"Injected\";v=\"99", "Brand";v="1\\2"`, + "Sec-CH-UA-Full-Version-List": `"Chrome";v="1\", \"Injected\";v=\"99", "Brand";v="1\\2"`, + }, + }, + { + name: "SUA with special characters requiring escaping (RFC 9651)", + device: openrtb2.Device{ + SUA: &openrtb2.UserAgent{ + Browsers: []openrtb2.BrandVersion{ + {Brand: `Test"Brand`, Version: []string{"1", "0"}}, + {Brand: `Test\Brand`, Version: []string{"2", "0"}}, + }, + Platform: &openrtb2.BrandVersion{ + Brand: `OS"Name`, + Version: []string{"1"}, + }, + Model: `Device"Model\Name`, + Architecture: `arch\test`, + }, + }, + rawHeaders: map[string]string{}, + expected: map[string]string{ + "Sec-CH-UA": `"Test\"Brand";v="1.0", "Test\\Brand";v="2.0"`, + "Sec-CH-UA-Full-Version-List": `"Test\"Brand";v="1.0", "Test\\Brand";v="2.0"`, + "Sec-CH-UA-Platform": `"OS\"Name"`, + "Sec-CH-UA-Platform-Version": `"1"`, + "Sec-CH-UA-Model": `"Device\"Model\\Name"`, + "Sec-CH-UA-Arch": `"arch\\test"`, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := makeHeaders(test.device, test.rawHeaders) + assert.Equal(t, test.expected, result) + }) + } +} diff --git a/modules/scope3/rtd/README.md b/modules/scope3/rtd/README.md index 3db4d447e2..bdaa5e5893 100644 --- a/modules/scope3/rtd/README.md +++ b/modules/scope3/rtd/README.md @@ -19,10 +19,12 @@ hooks: auth_key: ${SCOPE3_API_KEY} # Set SCOPE3_API_KEY environment variable endpoint: https://rtdp.scope3.com/prebid/prebid timeout_ms: 1000 - cache_ttl_seconds: 60 # Cache segments for 60 seconds (default) - add_to_targeting: false # Set to true to add segments as individual targeting keys for GAM - masking: # Optional privacy masking configuration - enabled: true # Enable field masking before sending to Scope3 + cache_ttl_seconds: 60 # Cache segments for 60 seconds (default) + add_to_targeting: false # Set to true to add segments as individual targeting keys for GAM + add_scope3_targeting_section: false # Also set targeting in dedicated scope3 section + single_segment_key: "" # When set, adds all segments as a comma separated value under a single targeting key + masking: # Optional privacy masking configuration + enabled: true # Enable field masking before sending to Scope3 geo: preserve_metro: true # Preserve DMA code (default: true) preserve_zip: true # Preserve postal code (default: true) @@ -46,12 +48,12 @@ hooks: hook_sequence: - module_code: "scope3.rtd" hook_impl_code: "HandleEntrypointHook" - raw_auction_request: + auction_processed: groups: - timeout: 2000 hook_sequence: - module_code: "scope3.rtd" - hook_impl_code: "HandleRawAuctionHook" + hook_impl_code: "HandleAuctionProcessedHook" auction_response: groups: - timeout: 5 @@ -73,6 +75,7 @@ hooks: "timeout_ms": 1000, "cache_ttl_seconds": 60, "add_to_targeting": false, + "add_scope3_targeting_section": false, "masking": { "enabled": true, "geo": { @@ -306,7 +309,7 @@ The module forwards any fields that are not masked from the bid request to the S ### Auction Response Data The module adds audience segments to the auction response, giving publishers full control over how to use them: -1. **Publisher Flexibility**: Segments are always returned in `ext.scope3.segments` for the publisher to decide where to send +1. **Publisher Flexibility**: Segments are returned in `ext.scope3.segments` when configured for the publisher to decide where to send 2. **Google Ad Manager (GAM)**: Individual targeting keys are added when `add_to_targeting: true` (e.g., `gmp_eligible=true`) 3. **Other Ad Servers**: Publisher can forward segments to any ad server or system 4. **Analytics**: Segment data is available for reporting and analysis @@ -314,7 +317,7 @@ The module adds audience segments to the auction response, giving publishers ful ### Response Format Options The module provides segments in two formats: -**Always available:** +**When `add_scope3_targeting_section: true`:** ```json { "ext": { diff --git a/modules/scope3/rtd/async_request.go b/modules/scope3/rtd/async_request.go index 38c4663286..23f44b2df5 100644 --- a/modules/scope3/rtd/async_request.go +++ b/modules/scope3/rtd/async_request.go @@ -48,6 +48,6 @@ func (ar *AsyncRequest) fetchScope3SegmentsAsync(request *openrtb2.BidRequest) { } close(ar.Done) }() - ar.Segments, ar.Err = ar.Module.fetchScope3Segments(ar.Context, request) + ar.Segments, ar.Err = ar.fetchScope3Segments(ar.Context, request) }() } diff --git a/modules/scope3/rtd/masking.go b/modules/scope3/rtd/masking.go index d32689dacf..d8123aa20b 100644 --- a/modules/scope3/rtd/masking.go +++ b/modules/scope3/rtd/masking.go @@ -4,8 +4,8 @@ import ( "math" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/util/iterutil" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/iterutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // maskBidRequest creates a deep copy of the bid request with sensitive fields masked diff --git a/modules/scope3/rtd/module.go b/modules/scope3/rtd/module.go index 15fab4fc68..9ad4e61702 100644 --- a/modules/scope3/rtd/module.go +++ b/modules/scope3/rtd/module.go @@ -10,9 +10,7 @@ import ( "errors" "fmt" "hash" - "maps" "net/http" - "slices" "strings" "sync" "time" @@ -20,12 +18,13 @@ import ( "github.com/coocood/freecache" jsoniter "github.com/json-iterator/go" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/hooks/hookanalytics" - "github.com/prebid/prebid-server/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/modules/moduledeps" - "github.com/prebid/prebid-server/v3/util/iterutil" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/hooks/hookanalytics" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/modules/moduledeps" + "github.com/prebid/prebid-server/v4/util/iterutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/tidwall/sjson" ) // Builder is the entry point for the module @@ -90,31 +89,35 @@ func Builder(config json.RawMessage, deps moduledeps.ModuleDeps) (interface{}, e const ( // keys for miCtx - asyncRequestKey = "scope3.AsyncRequest" - scope3MacroKey = "scope3_macro" - scope3MacroSeparator = ";" + asyncRequestKey = "scope3.AsyncRequest" + scope3MacroKey = "scope3_macro" + scope3IncludeKey = "scope3_include" + scope3Separator = ";" + scope3CacheKeySeparator = "|" ) -var scope3MacroKeyPlusSeparator = scope3MacroKey + scope3MacroSeparator +var scope3MacroKeyPlusSeparator = scope3MacroKey + scope3Separator +var scope3IncludeKeyPlusSeparator = scope3IncludeKey + scope3Separator const DefaultScope3RTDURL = "https://rtdp.scope3.com/prebid/prebid" var ( // Declare hooks - _ hookstage.Entrypoint = (*Module)(nil) - _ hookstage.RawAuctionRequest = (*Module)(nil) - _ hookstage.AuctionResponse = (*Module)(nil) + _ hookstage.Entrypoint = (*Module)(nil) + _ hookstage.ProcessedAuctionRequest = (*Module)(nil) + _ hookstage.AuctionResponse = (*Module)(nil) ) // Config holds module configuration type Config struct { - Endpoint string `json:"endpoint"` - AuthKey string `json:"auth_key"` - Timeout int `json:"timeout_ms"` - CacheTTL int `json:"cache_ttl_seconds"` // Cache segments for this many seconds - CacheSize int `json:"cache_size"` // Maximum size of segment cache in bytes - AddToTargeting bool `json:"add_to_targeting"` // Add segments as individual targeting keys - Masking MaskingConfig `json:"masking"` // Privacy masking configuration + Endpoint string `json:"endpoint"` + AuthKey string `json:"auth_key"` + Timeout int `json:"timeout_ms"` + CacheTTL int `json:"cache_ttl_seconds"` // Cache segments for this many seconds + CacheSize int `json:"cache_size"` // Maximum size of segment cache in bytes + AddToTargeting bool `json:"add_to_targeting"` // Add segments as individual targeting keys + AddScope3TargetingSection bool `json:"add_scope3_targeting_section"` // Add segments as individual targeting keys in Scope3 targeting section + Masking MaskingConfig `json:"masking"` // Privacy masking configuration } // MaskingConfig controls what user data is masked before sending to Scope3 @@ -153,30 +156,19 @@ type userExt struct { // Response types for Scope3 API type Scope3Response struct { - Data []Scope3Data `json:"data"` + AEESignals `json:"aee_signals"` } -type Scope3Data struct { - Destination string `json:"destination"` - Imp []Scope3ImpData `json:"imp"` +type AEESignals struct { + Include []string `json:"include,omitempty"` + Exclude []string `json:"exclude,omitempty"` + Macro string `json:"macro,omitempty"` // base64 + Bidders []map[string]Bidder `json:"bidders,omitempty"` } -type Scope3ImpData struct { - ID string `json:"id"` - Ext *Scope3Ext `json:"ext,omitempty"` -} - -type Scope3Ext struct { - Scope3 *Scope3ExtData `json:"scope3"` -} - -type Scope3ExtData struct { - Segments []Scope3Segment `json:"segments"` - Macro string `json:"macro"` -} - -type Scope3Segment struct { - ID string `json:"id"` +type Bidder struct { + Segments []string `json:"segments,omitempty"` + Deals []string `json:"deals,omitempty"` } // Module implements the Scope3 RTD module @@ -194,24 +186,24 @@ func (m *Module) HandleEntrypointHook( miCtx hookstage.ModuleInvocationContext, payload hookstage.EntrypointPayload, ) (hookstage.HookResult[hookstage.EntrypointPayload], error) { + moduleContext := hookstage.NewModuleContext() + moduleContext.Set(asyncRequestKey, m.NewAsyncRequest(payload.Request)) // Initialize module context with sync.Map for thread-safe segment storage return hookstage.HookResult[hookstage.EntrypointPayload]{ - ModuleContext: hookstage.ModuleContext{ - asyncRequestKey: m.NewAsyncRequest(payload.Request), - }, + ModuleContext: moduleContext, }, nil } // HandleRawAuctionHook is called early in the auction to fetch Scope3 data -func (m *Module) HandleRawAuctionHook( +func (m *Module) HandleProcessedAuctionHook( ctx context.Context, miCtx hookstage.ModuleInvocationContext, - payload hookstage.RawAuctionRequestPayload, -) (hookstage.HookResult[hookstage.RawAuctionRequestPayload], error) { - var ret hookstage.HookResult[hookstage.RawAuctionRequestPayload] - analyticsNamePrefix := "HandleRawAuctionHook." + payload hookstage.ProcessedAuctionRequestPayload, +) (hookstage.HookResult[hookstage.ProcessedAuctionRequestPayload], error) { + var ret hookstage.HookResult[hookstage.ProcessedAuctionRequestPayload] + analyticsNamePrefix := "HandleProcessedAuctionHook." - asyncRequest, ok := miCtx.ModuleContext[asyncRequestKey].(*AsyncRequest) + request, ok := miCtx.ModuleContext.Get(asyncRequestKey) if !ok { // Log error but don't fail the auction ret.AnalyticsTags = hookanalytics.Analytics{ @@ -227,17 +219,16 @@ func (m *Module) HandleRawAuctionHook( return ret, nil } - // Parse OpenRTB request here rather than HandleProcessedAuctionHook to get a copy to avoid parallel mutation issues - var bidRequest openrtb2.BidRequest - if err := jsonutil.Unmarshal(payload, &bidRequest); err != nil { + asyncRequest, ok := request.(*AsyncRequest) + if !ok { // Log error but don't fail the auction ret.AnalyticsTags = hookanalytics.Analytics{ Activities: []hookanalytics.Activity{{ - Name: analyticsNamePrefix + "bidRequest.unmarshal", + Name: analyticsNamePrefix + asyncRequestKey, Status: hookanalytics.ActivityStatusError, Results: []hookanalytics.Result{{ Status: hookanalytics.ResultStatusError, - Values: map[string]interface{}{"error": err.Error()}, + Values: map[string]interface{}{"error": "failed to get async request from module context"}, }}, }}, } @@ -245,7 +236,7 @@ func (m *Module) HandleRawAuctionHook( } // Start async request to Scope3 - asyncRequest.fetchScope3SegmentsAsync(&bidRequest) + asyncRequest.fetchScope3SegmentsAsync(payload.Request.BidRequest) return ret, nil } @@ -258,7 +249,24 @@ func (m *Module) HandleAuctionResponseHook( ) (hookstage.HookResult[hookstage.AuctionResponsePayload], error) { analyticsNamePrefix := "HandleAuctionResponseHook." var ret hookstage.HookResult[hookstage.AuctionResponsePayload] - asyncRequest, ok := miCtx.ModuleContext[asyncRequestKey].(*AsyncRequest) + + request, ok := miCtx.ModuleContext.Get(asyncRequestKey) + if !ok { + // Log error but don't fail the auction + ret.AnalyticsTags = hookanalytics.Analytics{ + Activities: []hookanalytics.Activity{{ + Name: analyticsNamePrefix + asyncRequestKey, + Status: hookanalytics.ActivityStatusError, + Results: []hookanalytics.Result{{ + Status: hookanalytics.ResultStatusError, + Values: map[string]interface{}{"error": "failed to get async request from module context"}, + }}, + }}, + } + return ret, nil + } + + asyncRequest, ok := request.(*AsyncRequest) if !ok { // Log error but don't fail the auction ret.AnalyticsTags = hookanalytics.Analytics{ @@ -313,50 +321,64 @@ func (m *Module) HandleAuctionResponseHook( // Add segments to the auction response ret.ChangeSet.AddMutation( func(payload hookstage.AuctionResponsePayload) (hookstage.AuctionResponsePayload, error) { - // Add Scope3 segments to the response ext so publisher can use them - if payload.BidResponse.Ext == nil { - payload.BidResponse.Ext = json.RawMessage("{}") - } - - var extMap map[string]interface{} - if err = jsonutil.Unmarshal(payload.BidResponse.Ext, &extMap); err != nil { - extMap = make(map[string]interface{}) - } - // Add segments as individual targeting keys for GAM integration if m.cfg.AddToTargeting { - prebidMap, ok := extMap["prebid"].(map[string]interface{}) - if !ok { - prebidMap = make(map[string]interface{}) - extMap["prebid"] = prebidMap - } - targetingMap, ok := prebidMap["targeting"].(map[string]interface{}) - if !ok { - targetingMap = make(map[string]interface{}) - prebidMap["targeting"] = targetingMap - } // Add each segment as individual targeting key for _, segment := range segments { - if strings.HasPrefix(segment, scope3MacroKeyPlusSeparator) { - macroKeyVal := strings.Split(segment, scope3MacroSeparator) - if len(macroKeyVal) != 2 { - continue - } - targetingMap[macroKeyVal[0]] = macroKeyVal[1] - } else { - targetingMap[segment] = "true" + segmentKeyVal := strings.Split(segment, scope3Separator) + if len(segmentKeyVal) != 2 { + logger.Infof("Skipping malformed segment: %s", segment) + continue + } + newPayload, err := sjson.SetBytes(payload.BidResponse.Ext, "prebid.targeting."+segmentKeyVal[0], segmentKeyVal[1]) + if err != nil { + logger.Errorf("Failed to add targeting to bid: %v", err) + continue } + payload.BidResponse.Ext = newPayload } } - // Always add to a dedicated scope3 section for publisher flexibility - extMap["scope3"] = map[string]interface{}{ - "segments": segments, + // Add to a dedicated scope3 section for publisher flexibility when configured + if m.cfg.AddScope3TargetingSection { + newPayload, err := sjson.SetBytes(payload.BidResponse.Ext, "scope3.segments", segments) + if err != nil { + logger.Errorf("Failed to add scope3 section to bid response ext: %v", err) + } else { + payload.BidResponse.Ext = newPayload + } } - extResp, err := jsonutil.Marshal(extMap) - if err == nil { - payload.BidResponse.Ext = extResp + // also add to seatbid[].bid[] + for seatBid := range iterutil.SlicePointerValues(payload.BidResponse.SeatBid) { + for bid := range iterutil.SlicePointerValues(seatBid.Bid) { + // Add segments as individual targeting keys for GAM integration + if m.cfg.AddToTargeting { + for _, segment := range segments { + segmentKeyVal := strings.Split(segment, scope3Separator) + if len(segmentKeyVal) != 2 { + logger.Infof("Skipping malformed segment in bid targeting: %s", segment) + continue + } + newPayload, err := sjson.SetBytes(bid.Ext, "prebid.targeting."+segmentKeyVal[0], segmentKeyVal[1]) + if err != nil { + logger.Errorf("Failed to add targeting to bid: %v", err) + continue + } + bid.Ext = newPayload + } + } + + // Always add to a dedicated scope3 section for publisher flexibility + if m.cfg.AddScope3TargetingSection { + newPayload, err := sjson.SetBytes(bid.Ext, "scope3.segments", segments) + if err != nil { + logger.Errorf("Failed to add scope3 section to bid response ext: %v", err) + } else { + bid.Ext = newPayload + } + } + } } return payload, nil @@ -375,7 +397,7 @@ func (m *Module) fetchScope3Segments(ctx context.Context, bidRequest *openrtb2.B // Check cache first if segments, err := m.cache.Get(cacheKey); err == nil { - return strings.Split(string(segments), ","), nil + return strings.Split(string(segments), scope3CacheKeySeparator), nil } // Apply privacy masking before sending to Scope3 @@ -421,31 +443,17 @@ func (m *Module) fetchScope3Segments(ctx context.Context, bidRequest *openrtb2.B return nil, err } - // Extract unique segments (exclude destination) - segmentMap := make(map[string]bool) - var macro string - for data := range iterutil.SlicePointerValues(scope3Resp.Data) { - // Extract actual segments from impression-level data - for imp := range iterutil.SlicePointerValues(data.Imp) { - if imp.Ext != nil && imp.Ext.Scope3 != nil { - if imp.Ext.Scope3.Macro != "" { - macro = imp.Ext.Scope3.Macro - } - for segment := range iterutil.SlicePointerValues(imp.Ext.Scope3.Segments) { - segmentMap[segment.ID] = true - } - } - } + segments := []string{} + if len(scope3Resp.Include) > 0 { + segmentsStr := scope3IncludeKeyPlusSeparator + strings.Join(scope3Resp.Include, ",") + segments = append(segments, segmentsStr) } - - // Convert to slice - segments := slices.AppendSeq(make([]string, 0, len(segmentMap)), maps.Keys(segmentMap)) - if macro != "" { - segments = append(segments, scope3MacroKeyPlusSeparator+macro) + if scope3Resp.Macro != "" { + segments = append(segments, scope3MacroKeyPlusSeparator+scope3Resp.Macro) } // Cache the result - err = m.cache.Set(cacheKey, []byte(strings.Join(segments, ",")), m.cfg.CacheTTL) + err = m.cache.Set(cacheKey, []byte(strings.Join(segments, scope3CacheKeySeparator)), m.cfg.CacheTTL) if err != nil { logger.Infof("could not set segments in cache: %v", err) } diff --git a/modules/scope3/rtd/module_test.go b/modules/scope3/rtd/module_test.go index 8b46d3bbb8..6b40353cf0 100644 --- a/modules/scope3/rtd/module_test.go +++ b/modules/scope3/rtd/module_test.go @@ -15,9 +15,10 @@ import ( "github.com/coocood/freecache" "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/hooks/hookstage" - "github.com/prebid/prebid-server/v3/modules/moduledeps" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/hooks/hookstage" + "github.com/prebid/prebid-server/v4/modules/moduledeps" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -82,16 +83,19 @@ func TestHandleEntrypointHook(t *testing.T) { result, err := module.HandleEntrypointHook(ctx, miCtx, payload) assert.NoError(t, err) - assert.NotNil(t, result.ModuleContext[asyncRequestKey]) + asyncRequest, _ := result.ModuleContext.Get(asyncRequestKey) + assert.NotNil(t, asyncRequest) } func TestHandleAuctionResponseHook_NoSegments(t *testing.T) { module := &Module{} ctx := context.Background() miCtx := hookstage.ModuleInvocationContext{ - ModuleContext: hookstage.ModuleContext{ - "segments": &sync.Map{}, - }, + ModuleContext: func() *hookstage.ModuleContext { + mctx := hookstage.NewModuleContext() + mctx.Set("segments", &sync.Map{}) + return mctx + }(), } payload := hookstage.AuctionResponsePayload{} @@ -128,25 +132,13 @@ func TestScope3APIIntegration(t *testing.T) { // Return mock Scope3 response with segments response := `{ - "data": [ - { - "destination": "triplelift.com", - "imp": [ - { - "id": "test-imp-1", - "ext": { - "scope3": { - "macro": "test-macro", - "segments": [ - {"id": "gmp_eligible"}, - {"id": "gmp_plus_eligible"} - ] - } - } - } - ] - } - ] + "aee_signals": { + "include": [ + "gmp_eligible", + "gmp_plus_eligible" + ], + "macro": "test-macro" + } }` w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -197,34 +189,154 @@ func TestScope3APIIntegration(t *testing.T) { ctx := context.Background() segments, err := module.fetchScope3Segments(ctx, bidRequest) require.NoError(t, err) - assert.Len(t, segments, 3) - assert.ElementsMatch(t, segments, []string{"gmp_eligible", "gmp_plus_eligible", "scope3_macro;test-macro"}) - assert.NotContains(t, segments, "triplelift.com") // Should not include destination + assert.Len(t, segments, 2) + assert.ElementsMatch(t, segments, []string{"scope3_include;gmp_eligible,gmp_plus_eligible", "scope3_macro;test-macro"}) } -func TestScope3APIIntegrationWithTargeting(t *testing.T) { - // Create mock server that returns segments +func TestScope3APIIntegrationNoSegments(t *testing.T) { + // Create mock Scope3 API server mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Verify request method and headers + assert.Equal(t, "POST", r.Method) + assert.Equal(t, "application/json", r.Header.Get("Content-Type")) + assert.Equal(t, "test-auth-key", r.Header.Get("x-scope3-auth")) + + // Return mock Scope3 response with segments response := `{ - "data": [ + "aee_signals": {} + }` + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(response)) + })) + defer mockServer.Close() + + // Create module with mock server endpoint + config := json.RawMessage(`{ + "endpoint": "` + mockServer.URL + `", + "auth_key": "test-auth-key", + "timeout_ms": 1000, + "cache_ttl_seconds": 60, + "add_to_targeting": false + }`) + + moduleInterface, err := Builder(config, getTestModuleDeps(t)) + require.NoError(t, err) + module := moduleInterface.(*Module) + + // Create test bid request + width := int64(300) + height := int64(250) + bidRequest := &openrtb2.BidRequest{ + ID: "test-auction", + Imp: []openrtb2.Imp{{ + ID: "test-imp-1", + Banner: &openrtb2.Banner{W: &width, H: &height}, + }}, + Site: &openrtb2.Site{ + Domain: "example.com", + Page: "https://example.com/test-page", + }, + User: &openrtb2.User{ + ID: "test-user", + Ext: json.RawMessage(`{ + "eids": [ + { + "source": "liveramp.com", + "uids": [{"id": "test-ramp-id"}] + } + ] + }`), + }, + } + + // Test fetchScope3Segments + ctx := context.Background() + segments, err := module.fetchScope3Segments(ctx, bidRequest) + require.NoError(t, err) + assert.Len(t, segments, 0) + + // Test entrypoint hook + entrypointResult, err := module.HandleEntrypointHook(ctx, hookstage.ModuleInvocationContext{}, getTestEntrypointPayload(t)) + require.NoError(t, err) + asyncRequest, _ := entrypointResult.ModuleContext.Get(asyncRequestKey) + assert.NotNil(t, asyncRequest) + + payload := hookstage.ProcessedAuctionRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: bidRequest, + }, + } + + // Test raw auction hook + miCtx := hookstage.ModuleInvocationContext{ + ModuleContext: entrypointResult.ModuleContext, + } + _, err = module.HandleProcessedAuctionHook(ctx, miCtx, payload) + require.NoError(t, err) + + // Test auction response hook + responsePayload := hookstage.AuctionResponsePayload{ + BidResponse: &openrtb2.BidResponse{ + ID: "test-response", + Ext: json.RawMessage(`{}`), + SeatBid: []openrtb2.SeatBid{ { - "destination": "triplelift.com", - "imp": [ + Seat: "test-seat", + Bid: []openrtb2.Bid{ + { + ID: "test-bid-1", + ImpID: "test-imp-1", + Price: 1.0, + Ext: json.RawMessage(`{}`), + }, { - "id": "test-imp-1", - "ext": { - "scope3": { - "macro": "test-macro", - "segments": [ - {"id": "test_segment_1"}, - {"id": "test_segment_2"} - ] - } - } - } - ] - } - ] + ID: "test-bid-2", + ImpID: "test-imp-2", + Price: 2.0, + Ext: json.RawMessage(`{}`), + }, + }, + }, + }, + }, + } + + responseResult, err := module.HandleAuctionResponseHook(ctx, miCtx, responsePayload) + require.NoError(t, err) + + // Verify the response was modified + assert.True(t, len(responseResult.ChangeSet.Mutations()) > 0) + + // Apply the mutations and check the result + modifiedPayload := responsePayload + for _, mutation := range responseResult.ChangeSet.Mutations() { + var err error + modifiedPayload, err = mutation.Apply(modifiedPayload) + require.NoError(t, err) + } + + // Parse the modified response + var extMap map[string]interface{} + err = json.Unmarshal(modifiedPayload.BidResponse.Ext, &extMap) + require.NoError(t, err) + + // Verify scope3 section exists + _, exists := extMap["scope3"].(map[string]interface{}) + require.False(t, exists) +} + +func TestScope3APIIntegrationWithTargeting(t *testing.T) { + // Create mock server that returns segments + mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + response := `{ + "aee_signals": { + "include": [ + "test_segment_1", + "test_segment_2" + ], + "macro": "test-macro" + } }` w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -237,7 +349,8 @@ func TestScope3APIIntegrationWithTargeting(t *testing.T) { "endpoint": "` + mockServer.URL + `", "auth_key": "test-auth-key", "timeout_ms": 1000, - "add_to_targeting": true + "add_to_targeting": true, + "add_scope3_targeting_section": true }`) moduleInterface, err := Builder(config, getTestModuleDeps(t)) @@ -250,29 +363,38 @@ func TestScope3APIIntegrationWithTargeting(t *testing.T) { // Test entrypoint hook entrypointResult, err := module.HandleEntrypointHook(ctx, hookstage.ModuleInvocationContext{}, getTestEntrypointPayload(t)) require.NoError(t, err) - assert.NotNil(t, entrypointResult.ModuleContext[asyncRequestKey]) + asyncRequest, _ := entrypointResult.ModuleContext.Get(asyncRequestKey) + assert.NotNil(t, asyncRequest) // Create test request payload width := int64(300) height := int64(250) - bidRequest := openrtb2.BidRequest{ - ID: "test-auction", - Imp: []openrtb2.Imp{{ - ID: "test-imp-1", - Banner: &openrtb2.Banner{W: &width, H: &height}, - }}, - Site: &openrtb2.Site{ - Domain: "example.com", - Page: "https://example.com/test", + payload := hookstage.ProcessedAuctionRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + ID: "test-auction", + Imp: []openrtb2.Imp{ + { + ID: "test-imp-1", + Banner: &openrtb2.Banner{W: &width, H: &height}, + }, + { + ID: "test-imp-2", + Banner: &openrtb2.Banner{W: &width, H: &height}, + }}, + Site: &openrtb2.Site{ + Domain: "example.com", + Page: "https://example.com/test", + }, + }, }, } - requestPayload, _ := json.Marshal(bidRequest) // Test raw auction hook miCtx := hookstage.ModuleInvocationContext{ ModuleContext: entrypointResult.ModuleContext, } - _, err = module.HandleRawAuctionHook(ctx, miCtx, requestPayload) + _, err = module.HandleProcessedAuctionHook(ctx, miCtx, payload) require.NoError(t, err) // Test auction response hook @@ -280,6 +402,42 @@ func TestScope3APIIntegrationWithTargeting(t *testing.T) { BidResponse: &openrtb2.BidResponse{ ID: "test-response", Ext: json.RawMessage(`{}`), + SeatBid: []openrtb2.SeatBid{ + { + Seat: "test-seat", + Bid: []openrtb2.Bid{ + { + ID: "test-bid-1", + ImpID: "test-imp-1", + Price: 1.0, + Ext: json.RawMessage(`{}`), + }, + { + ID: "test-bid-2", + ImpID: "test-imp-2", + Price: 2.0, + Ext: json.RawMessage(`{}`), + }, + }, + }, + { + Seat: "test-seat2", + Bid: []openrtb2.Bid{ + { + ID: "test-bid-3", + ImpID: "test-imp-3", + Price: 1.0, + Ext: json.RawMessage(`{}`), + }, + { + ID: "test-bid-4", + ImpID: "test-imp-4", + Price: 2.0, + Ext: json.RawMessage(`{}`), + }, + }, + }, + }, }, } @@ -307,7 +465,159 @@ func TestScope3APIIntegrationWithTargeting(t *testing.T) { require.True(t, exists) segments, exists := scope3Data["segments"].([]interface{}) require.True(t, exists) - assert.Len(t, segments, 3) + assert.Len(t, segments, 2) + + // Verify targeting section exists (add_to_targeting: true) + prebidData, exists := extMap["prebid"].(map[string]interface{}) + require.True(t, exists, "prebid section missing") + targetingData, exists := prebidData["targeting"].(map[string]interface{}) + require.True(t, exists, "targeting section missing") + + // Check individual targeting keys + assert.Equal(t, "test_segment_1,test_segment_2", targetingData["scope3_include"]) + assert.Equal(t, "test-macro", targetingData["scope3_macro"]) + + // check seatbid + assert.Len(t, modifiedPayload.BidResponse.SeatBid, 2) + assert.Len(t, modifiedPayload.BidResponse.SeatBid[0].Bid, 2) + assert.Len(t, modifiedPayload.BidResponse.SeatBid[1].Bid, 2) + + for _, seatbid := range modifiedPayload.BidResponse.SeatBid { + for _, bid := range seatbid.Bid { + // Parse the modified response + var extBidMap map[string]interface{} + err = json.Unmarshal(bid.Ext, &extBidMap) + require.NoError(t, err) + + // Verify scope3 section exists + scope3DataSeatBid, exists := extBidMap["scope3"].(map[string]interface{}) + require.True(t, exists, "scope3 section missing") + segmentsSeatBid, exists := scope3DataSeatBid["segments"].([]interface{}) + require.True(t, exists, "segments section missing") + assert.Len(t, segmentsSeatBid, 2) + + // Verify targeting section exists (add_to_targeting: true) + prebidDataSeatBid, exists := extBidMap["prebid"].(map[string]interface{}) + require.True(t, exists, "prebid section missing") + targetingDataSeatBid, exists := prebidDataSeatBid["targeting"].(map[string]interface{}) + require.True(t, exists, "targeting section missing") + + // Check individual targeting keys + assert.Equal(t, "test_segment_1,test_segment_2", targetingDataSeatBid["scope3_include"]) + assert.Equal(t, "test-macro", targetingDataSeatBid["scope3_macro"]) + } + } +} + +func TestScope3APIIntegrationWithTargetingNoScope3Section(t *testing.T) { + // Create mock server that returns segments + mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + response := `{ + "aee_signals": { + "include": [ + "test_segment_1", + "test_segment_2" + ], + "macro": "test-macro" + } + }` + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(response)) + })) + defer mockServer.Close() + + // Create module with targeting enabled + config := json.RawMessage(`{ + "endpoint": "` + mockServer.URL + `", + "auth_key": "test-auth-key", + "timeout_ms": 1000, + "add_to_targeting": true, + "add_scope3_targeting_section": false + }`) + + moduleInterface, err := Builder(config, getTestModuleDeps(t)) + require.NoError(t, err) + module := moduleInterface.(*Module) + + // Test full hook workflow + ctx := context.Background() + + // Test entrypoint hook + entrypointResult, err := module.HandleEntrypointHook(ctx, hookstage.ModuleInvocationContext{}, getTestEntrypointPayload(t)) + require.NoError(t, err) + asyncRequest, _ := entrypointResult.ModuleContext.Get(asyncRequestKey) + assert.NotNil(t, asyncRequest) + + // Create test request payload + width := int64(300) + height := int64(250) + payload := hookstage.ProcessedAuctionRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + ID: "test-auction", + Imp: []openrtb2.Imp{{ + ID: "test-imp-1", + Banner: &openrtb2.Banner{W: &width, H: &height}, + }}, + Site: &openrtb2.Site{ + Domain: "example.com", + Page: "https://example.com/test", + }, + }, + }, + } + + // Test raw auction hook + miCtx := hookstage.ModuleInvocationContext{ + ModuleContext: entrypointResult.ModuleContext, + } + _, err = module.HandleProcessedAuctionHook(ctx, miCtx, payload) + require.NoError(t, err) + + // Test auction response hook + responsePayload := hookstage.AuctionResponsePayload{ + BidResponse: &openrtb2.BidResponse{ + ID: "test-response", + Ext: json.RawMessage(`{}`), + SeatBid: []openrtb2.SeatBid{ + { + Seat: "test-seat", + Bid: []openrtb2.Bid{ + { + ID: "test-bid-1", + ImpID: "test-imp-1", + Price: 1.0, + Ext: json.RawMessage(`{}`), + }, + }, + }, + }, + }, + } + + responseResult, err := module.HandleAuctionResponseHook(ctx, miCtx, responsePayload) + require.NoError(t, err) + + // Verify the response was modified + assert.True(t, len(responseResult.ChangeSet.Mutations()) > 0) + + // Apply the mutations and check the result + modifiedPayload := responsePayload + for _, mutation := range responseResult.ChangeSet.Mutations() { + var err error + modifiedPayload, err = mutation.Apply(modifiedPayload) + require.NoError(t, err) + } + + // Parse the modified response + var extMap map[string]interface{} + err = json.Unmarshal(modifiedPayload.BidResponse.Ext, &extMap) + require.NoError(t, err) + + // Verify scope3 section exists + _, exists := extMap["scope3"].(map[string]interface{}) + require.False(t, exists) // Verify targeting section exists (add_to_targeting: true) prebidData, exists := extMap["prebid"].(map[string]interface{}) @@ -316,33 +626,44 @@ func TestScope3APIIntegrationWithTargeting(t *testing.T) { require.True(t, exists) // Check individual targeting keys - assert.Equal(t, "true", targetingData["test_segment_1"]) - assert.Equal(t, "true", targetingData["test_segment_2"]) + assert.Equal(t, "test_segment_1,test_segment_2", targetingData["scope3_include"]) assert.Equal(t, "test-macro", targetingData["scope3_macro"]) + + // check seatbid + assert.Len(t, modifiedPayload.BidResponse.SeatBid, 1) + assert.Len(t, modifiedPayload.BidResponse.SeatBid[0].Bid, 1) + + // Parse the modified response + var extBidMap map[string]interface{} + err = json.Unmarshal(modifiedPayload.BidResponse.SeatBid[0].Bid[0].Ext, &extBidMap) + require.NoError(t, err) + + // Verify scope3 section exists + _, exists = extBidMap["scope3"].(map[string]interface{}) + require.False(t, exists) + + // Verify targeting section exists (add_to_targeting: true) + prebidDataSeatBid, exists := extBidMap["prebid"].(map[string]interface{}) + require.True(t, exists, "prebid section missing") + targetingDataSeatBid, exists := prebidDataSeatBid["targeting"].(map[string]interface{}) + require.True(t, exists, "targeting section missing") + + // Check individual targeting keys + assert.Equal(t, "test_segment_1,test_segment_2", targetingDataSeatBid["scope3_include"]) + assert.Equal(t, "test-macro", targetingDataSeatBid["scope3_macro"]) } func TestScope3APIIntegrationWithExistingPrebidTargeting(t *testing.T) { // Create mock server that returns segments mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { response := `{ - "data": [ - { - "destination": "triplelift.com", - "imp": [ - { - "id": "test-imp-1", - "ext": { - "scope3": { - "segments": [ - {"id": "test_segment_1"}, - {"id": "test_segment_2"} - ] - } - } - } - ] - } - ] + "aee_signals": { + "include": [ + "test_segment_1", + "test_segment_2" + ], + "macro": "test-macro" + } }` w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -355,7 +676,8 @@ func TestScope3APIIntegrationWithExistingPrebidTargeting(t *testing.T) { "endpoint": "` + mockServer.URL + `", "auth_key": "test-auth-key", "timeout_ms": 1000, - "add_to_targeting": true + "add_to_targeting": true, + "add_scope3_targeting_section": true }`) moduleInterface, err := Builder(config, getTestModuleDeps(t)) @@ -368,29 +690,33 @@ func TestScope3APIIntegrationWithExistingPrebidTargeting(t *testing.T) { // Test entrypoint hook entrypointResult, err := module.HandleEntrypointHook(ctx, hookstage.ModuleInvocationContext{}, getTestEntrypointPayload(t)) require.NoError(t, err) - assert.NotNil(t, entrypointResult.ModuleContext[asyncRequestKey]) + asyncRequest, _ := entrypointResult.ModuleContext.Get(asyncRequestKey) + assert.NotNil(t, asyncRequest) // Create test request payload width := int64(300) height := int64(250) - bidRequest := openrtb2.BidRequest{ - ID: "test-auction", - Imp: []openrtb2.Imp{{ - ID: "test-imp-1", - Banner: &openrtb2.Banner{W: &width, H: &height}, - }}, - Site: &openrtb2.Site{ - Domain: "example.com", - Page: "https://example.com/test", + payload := hookstage.ProcessedAuctionRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + ID: "test-auction", + Imp: []openrtb2.Imp{{ + ID: "test-imp-1", + Banner: &openrtb2.Banner{W: &width, H: &height}, + }}, + Site: &openrtb2.Site{ + Domain: "example.com", + Page: "https://example.com/test", + }, + }, }, } - requestPayload, _ := json.Marshal(bidRequest) // Test raw auction hook miCtx := hookstage.ModuleInvocationContext{ ModuleContext: entrypointResult.ModuleContext, } - _, err = module.HandleRawAuctionHook(ctx, miCtx, requestPayload) + _, err = module.HandleProcessedAuctionHook(ctx, miCtx, payload) require.NoError(t, err) // Test auction response hook @@ -434,33 +760,21 @@ func TestScope3APIIntegrationWithExistingPrebidTargeting(t *testing.T) { require.True(t, exists) // Check individual targeting keys - assert.Equal(t, "true", targetingData["segment_existing"]) - assert.Equal(t, "true", targetingData["test_segment_1"]) - assert.Equal(t, "true", targetingData["test_segment_2"]) + assert.Equal(t, "test_segment_1,test_segment_2", targetingData["scope3_include"]) + assert.Equal(t, "test-macro", targetingData["scope3_macro"]) } func TestScope3APIIntegrationWithExistingPrebidNoTargeting(t *testing.T) { // Create mock server that returns segments mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { response := `{ - "data": [ - { - "destination": "triplelift.com", - "imp": [ - { - "id": "test-imp-1", - "ext": { - "scope3": { - "segments": [ - {"id": "test_segment_1"}, - {"id": "test_segment_2"} - ] - } - } - } - ] - } - ] + "aee_signals": { + "include": [ + "test_segment_1", + "test_segment_2" + ], + "macro": "test-macro" + } }` w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -473,7 +787,8 @@ func TestScope3APIIntegrationWithExistingPrebidNoTargeting(t *testing.T) { "endpoint": "` + mockServer.URL + `", "auth_key": "test-auth-key", "timeout_ms": 1000, - "add_to_targeting": true + "add_to_targeting": true, + "add_scope3_targeting_section": true }`) moduleInterface, err := Builder(config, getTestModuleDeps(t)) @@ -486,29 +801,33 @@ func TestScope3APIIntegrationWithExistingPrebidNoTargeting(t *testing.T) { // Test entrypoint hook entrypointResult, err := module.HandleEntrypointHook(ctx, hookstage.ModuleInvocationContext{}, getTestEntrypointPayload(t)) require.NoError(t, err) - assert.NotNil(t, entrypointResult.ModuleContext[asyncRequestKey]) + asyncRequest, _ := entrypointResult.ModuleContext.Get(asyncRequestKey) + assert.NotNil(t, asyncRequest) // Create test request payload width := int64(300) height := int64(250) - bidRequest := openrtb2.BidRequest{ - ID: "test-auction", - Imp: []openrtb2.Imp{{ - ID: "test-imp-1", - Banner: &openrtb2.Banner{W: &width, H: &height}, - }}, - Site: &openrtb2.Site{ - Domain: "example.com", - Page: "https://example.com/test", + payload := hookstage.ProcessedAuctionRequestPayload{ + Request: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + ID: "test-auction", + Imp: []openrtb2.Imp{{ + ID: "test-imp-1", + Banner: &openrtb2.Banner{W: &width, H: &height}, + }}, + Site: &openrtb2.Site{ + Domain: "example.com", + Page: "https://example.com/test", + }, + }, }, } - requestPayload, _ := json.Marshal(bidRequest) // Test raw auction hook miCtx := hookstage.ModuleInvocationContext{ ModuleContext: entrypointResult.ModuleContext, } - _, err = module.HandleRawAuctionHook(ctx, miCtx, requestPayload) + _, err = module.HandleProcessedAuctionHook(ctx, miCtx, payload) require.NoError(t, err) // Test auction response hook @@ -552,8 +871,8 @@ func TestScope3APIIntegrationWithExistingPrebidNoTargeting(t *testing.T) { require.True(t, exists) // Check individual targeting keys - assert.Equal(t, "true", targetingData["test_segment_1"]) - assert.Equal(t, "true", targetingData["test_segment_2"]) + assert.Equal(t, "test_segment_1,test_segment_2", targetingData["scope3_include"]) + assert.Equal(t, "test-macro", targetingData["scope3_macro"]) } func TestScope3APIError(t *testing.T) { diff --git a/modules/shutdown.go b/modules/shutdown.go index ae769ddf5e..d8be00b214 100644 --- a/modules/shutdown.go +++ b/modules/shutdown.go @@ -1,7 +1,7 @@ package modules import ( - "github.com/prebid/prebid-server/v3/logger" + "github.com/prebid/prebid-server/v4/logger" ) // Shutdowner is an interface that defines a method for shutting down modules. diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index d0a2841001..bc8cd14770 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -33,15 +33,11 @@ var coreBidderNames []BidderName = []BidderName{ BidderAdmatic, BidderAdmixer, BidderAdnuntius, - BidderAdOcean, - BidderAdoppler, BidderAdot, BidderAdpone, BidderAdprime, BidderAdquery, BidderAdrino, - BidderAdsInteractive, - BidderAdsinteractive, BidderAdtarget, BidderAdtrgtme, BidderAdtelligent, @@ -58,6 +54,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderAkcelo, BidderAlgorix, BidderAlkimi, + BidderAllianceGravity, BidderAMX, BidderApacdex, BidderAppnexus, @@ -71,6 +68,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderBeachfront, BidderBeintoo, BidderBematterfull, + BidderBeop, BidderBetween, BidderBeyondMedia, BidderBidmachine, @@ -115,15 +113,17 @@ var coreBidderNames []BidderName = []BidderName{ BidderDisplayio, BidderEdge226, BidderDmx, - BidderDXKulture, BidderDriftPixel, + BidderElementalTV, BidderEmtv, BidderEmxDigital, BidderEPlanning, BidderEpom, BidderEscalax, + BidderEskimi, BidderEVolution, BidderExco, + BidderEzoic, BidderFeedAd, BidderFlatads, BidderFlipp, @@ -134,7 +134,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderGamoshi, BidderGlobalsun, BidderGoldbach, - BidderGothamads, BidderGrid, BidderGumGum, BidderHuaweiAds, @@ -144,8 +143,8 @@ var coreBidderNames []BidderName = []BidderName{ BidderInfyTV, BidderInMobi, BidderInsticator, + BidderIntenze, BidderInteractiveoffers, - BidderIntertech, BidderInvibes, BidderIQX, BidderIQZone, @@ -204,7 +203,9 @@ var coreBidderNames []BidderName = []BidderName{ BidderOwnAdx, BidderPangle, BidderPGAMSsp, + BidderPixfuture, BidderPlaydigo, + BidderProxistore, BidderPubmatic, BidderPubrise, BidderPubnative, @@ -220,11 +221,12 @@ var coreBidderNames []BidderName = []BidderName{ BidderRise, BidderRoulax, BidderRTBHouse, + BidderRTBStack, BidderRubicon, BidderSeedingAlliance, BidderSeedtag, BidderSaLunaMedia, - BidderScreencore, + BidderScalibur, BidderSharethrough, BidderShowheroes, BidderSilverMob, @@ -243,11 +245,16 @@ var coreBidderNames []BidderName = []BidderName{ BidderSovrnXsp, BidderSparteo, BidderSspBC, + BidderStackAdapt, BidderStartIO, BidderStroeerCore, + BidderSynapseHX, BidderTaboola, + BidderTAdvertisingBlis, BidderTappx, + BidderTargetVideo, BidderTeads, + BidderTeal, BidderTelaria, BidderTeqBlaze, BidderTheadx, @@ -258,6 +265,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderTriplelift, BidderTripleliftNative, BidderTrustedstack, + BidderTrustX, BidderUcfunnel, BidderUndertone, BidderUnicorn, @@ -410,15 +418,11 @@ const ( BidderAdmatic BidderName = "admatic" BidderAdmixer BidderName = "admixer" BidderAdnuntius BidderName = "adnuntius" - BidderAdOcean BidderName = "adocean" - BidderAdoppler BidderName = "adoppler" BidderAdot BidderName = "adot" BidderAdpone BidderName = "adpone" BidderAdprime BidderName = "adprime" BidderAdquery BidderName = "adquery" BidderAdrino BidderName = "adrino" - BidderAdsInteractive BidderName = "ads_interactive" - BidderAdsinteractive BidderName = "adsinteractive" BidderAdtarget BidderName = "adtarget" BidderAdtrgtme BidderName = "adtrgtme" BidderAdTonos BidderName = "adtonos" @@ -435,6 +439,7 @@ const ( BidderAkcelo BidderName = "akcelo" BidderAlgorix BidderName = "algorix" BidderAlkimi BidderName = "alkimi" + BidderAllianceGravity BidderName = "alliance_gravity" BidderAMX BidderName = "amx" BidderApacdex BidderName = "apacdex" BidderAppnexus BidderName = "appnexus" @@ -448,6 +453,7 @@ const ( BidderBeachfront BidderName = "beachfront" BidderBeintoo BidderName = "beintoo" BidderBematterfull BidderName = "bematterfull" + BidderBeop BidderName = "beop" BidderBetween BidderName = "between" BidderBeyondMedia BidderName = "beyondmedia" BidderBidmachine BidderName = "bidmachine" @@ -492,15 +498,17 @@ const ( BidderDisplayio BidderName = "displayio" BidderEdge226 BidderName = "edge226" BidderDmx BidderName = "dmx" - BidderDXKulture BidderName = "dxkulture" BidderDriftPixel BidderName = "driftpixel" + BidderElementalTV BidderName = "elementaltv" BidderEmtv BidderName = "emtv" BidderEmxDigital BidderName = "emx_digital" BidderEPlanning BidderName = "eplanning" BidderEpom BidderName = "epom" BidderEscalax BidderName = "escalax" + BidderEskimi BidderName = "eskimi" BidderExco BidderName = "exco" BidderEVolution BidderName = "e_volution" + BidderEzoic BidderName = "ezoic" BidderFeedAd BidderName = "feedad" BidderFlatads BidderName = "flatads" BidderFlipp BidderName = "flipp" @@ -511,7 +519,6 @@ const ( BidderGamoshi BidderName = "gamoshi" BidderGlobalsun BidderName = "globalsun" BidderGoldbach BidderName = "goldbach" - BidderGothamads BidderName = "gothamads" BidderGrid BidderName = "grid" BidderGumGum BidderName = "gumgum" BidderHuaweiAds BidderName = "huaweiads" @@ -521,8 +528,8 @@ const ( BidderInfyTV BidderName = "infytv" BidderInMobi BidderName = "inmobi" BidderInsticator BidderName = "insticator" + BidderIntenze BidderName = "intenze" BidderInteractiveoffers BidderName = "interactiveoffers" - BidderIntertech BidderName = "intertech" BidderInvibes BidderName = "invibes" BidderIQX BidderName = "iqx" BidderIQZone BidderName = "iqzone" @@ -582,7 +589,9 @@ const ( BidderOwnAdx BidderName = "ownadx" BidderPangle BidderName = "pangle" BidderPGAMSsp BidderName = "pgamssp" + BidderPixfuture BidderName = "pixfuture" BidderPlaydigo BidderName = "playdigo" + BidderProxistore BidderName = "proxistore" BidderPubmatic BidderName = "pubmatic" BidderPubrise BidderName = "pubrise" BidderPubnative BidderName = "pubnative" @@ -598,11 +607,12 @@ const ( BidderRise BidderName = "rise" BidderRoulax BidderName = "roulax" BidderRTBHouse BidderName = "rtbhouse" + BidderRTBStack BidderName = "rtbstack" BidderRubicon BidderName = "rubicon" BidderSeedingAlliance BidderName = "seedingAlliance" BidderSeedtag BidderName = "seedtag" BidderSaLunaMedia BidderName = "sa_lunamedia" - BidderScreencore BidderName = "screencore" + BidderScalibur BidderName = "scalibur" BidderSharethrough BidderName = "sharethrough" BidderShowheroes BidderName = "showheroes" BidderSilverMob BidderName = "silvermob" @@ -621,11 +631,16 @@ const ( BidderSovrnXsp BidderName = "sovrnXsp" BidderSparteo BidderName = "sparteo" BidderSspBC BidderName = "sspBC" + BidderStackAdapt BidderName = "stackadapt" BidderStartIO BidderName = "startio" BidderStroeerCore BidderName = "stroeerCore" + BidderSynapseHX BidderName = "synapseHX" BidderTaboola BidderName = "taboola" + BidderTAdvertisingBlis BidderName = "tadvertising_blis" BidderTappx BidderName = "tappx" + BidderTargetVideo BidderName = "targetVideo" BidderTeads BidderName = "teads" + BidderTeal BidderName = "teal" BidderTelaria BidderName = "telaria" BidderTeqBlaze BidderName = "teqblaze" BidderTheadx BidderName = "theadx" @@ -635,6 +650,7 @@ const ( BidderTriplelift BidderName = "triplelift" BidderTripleliftNative BidderName = "triplelift_native" BidderTrustedstack BidderName = "trustedstack" + BidderTrustX BidderName = "trustx" BidderUcfunnel BidderName = "ucfunnel" BidderUndertone BidderName = "undertone" BidderUnicorn BidderName = "unicorn" diff --git a/openrtb_ext/convert_down_test.go b/openrtb_ext/convert_down_test.go index 684ae5cda4..0d295872cd 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/v3/errortypes" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/deal_tier.go b/openrtb_ext/deal_tier.go index b0f2675d66..c9818479fd 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/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/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 6808f90a0d..f85390ed26 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/v3/errortypes" + "github.com/prebid/prebid-server/v4/errortypes" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/device.go b/openrtb_ext/device.go index 2107a3081f..feb362e502 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/v3/errortypes" + "github.com/prebid/prebid-server/v4/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 52b679fda3..d634876143 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/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/floors.go b/openrtb_ext/floors.go index 1faa629232..93667e7d36 100644 --- a/openrtb_ext/floors.go +++ b/openrtb_ext/floors.go @@ -4,7 +4,7 @@ import ( "maps" "slices" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) // Defines strings for FetchStatus diff --git a/openrtb_ext/floors_test.go b/openrtb_ext/floors_test.go index df7d1e5dc2..e80ba28a03 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/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/imp_adocean.go b/openrtb_ext/imp_adocean.go deleted file mode 100644 index 1dd64d284e..0000000000 --- a/openrtb_ext/imp_adocean.go +++ /dev/null @@ -1,7 +0,0 @@ -package openrtb_ext - -type ExtImpAdOcean struct { - EmitterPrefix string `json:"emitterPrefix"` - MasterID string `json:"masterId"` - SlaveID string `json:"slaveId"` -} diff --git a/openrtb_ext/imp_adoppler.go b/openrtb_ext/imp_adoppler.go deleted file mode 100644 index 9d4d5e5ca0..0000000000 --- a/openrtb_ext/imp_adoppler.go +++ /dev/null @@ -1,6 +0,0 @@ -package openrtb_ext - -type ExtImpAdoppler struct { - Client string `json:"client"` - AdUnit string `json:"adunit"` -} diff --git a/openrtb_ext/imp_ads_interactive.go b/openrtb_ext/imp_ads_interactive.go deleted file mode 100644 index f7a02e2dd2..0000000000 --- a/openrtb_ext/imp_ads_interactive.go +++ /dev/null @@ -1,6 +0,0 @@ -package openrtb_ext - -type ImpExtAdsInteractive struct { - PlacementID string `json:"placementId"` - EndpointID string `json:"endpointId"` -} diff --git a/openrtb_ext/imp_adsinteractive.go b/openrtb_ext/imp_adsinteractive.go deleted file mode 100644 index c382b2d6e5..0000000000 --- a/openrtb_ext/imp_adsinteractive.go +++ /dev/null @@ -1,5 +0,0 @@ -package openrtb_ext - -type ImpExtAdsinteractive struct { - AdUnit string `json:"adUnit"` -} diff --git a/openrtb_ext/imp_alliance_gravity.go b/openrtb_ext/imp_alliance_gravity.go new file mode 100644 index 0000000000..f63c46fe2b --- /dev/null +++ b/openrtb_ext/imp_alliance_gravity.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ExtImpAllianceGravity struct { + SrId string `json:"srid"` +} diff --git a/openrtb_ext/imp_appnexus.go b/openrtb_ext/imp_appnexus.go index bde37bdc9d..e5c43fcf54 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/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/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 52e42d4d53..5cf268a793 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/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/imp_beop.go b/openrtb_ext/imp_beop.go new file mode 100644 index 0000000000..797ac92ef0 --- /dev/null +++ b/openrtb_ext/imp_beop.go @@ -0,0 +1,7 @@ +package openrtb_ext + +type ExtImpBeop struct { + BeopPublisherID string `json:"pid,omitempty"` + BeopNetworkID string `json:"nid,omitempty"` + BeopNetworkPartnerID string `json:"nptnid,omitempty"` +} diff --git a/openrtb_ext/imp_connectad.go b/openrtb_ext/imp_connectad.go index 4affaed1ea..528636f498 100644 --- a/openrtb_ext/imp_connectad.go +++ b/openrtb_ext/imp_connectad.go @@ -1,6 +1,6 @@ package openrtb_ext -import "github.com/prebid/prebid-server/v3/util/jsonutil" +import "github.com/prebid/prebid-server/v4/util/jsonutil" type ExtImpConnectAd struct { NetworkID jsonutil.StringInt `json:"networkId"` diff --git a/openrtb_ext/imp_dxkulture.go b/openrtb_ext/imp_dxkulture.go deleted file mode 100644 index 4b507c5524..0000000000 --- a/openrtb_ext/imp_dxkulture.go +++ /dev/null @@ -1,7 +0,0 @@ -package openrtb_ext - -// ExtImpDXKulture defines the contract for bidrequest.imp[i].ext.prebid.bidder.dxkulture -type ExtImpDXKulture struct { - PublisherId string `json:"publisherId"` - PlacementId string `json:"placementId"` -} diff --git a/openrtb_ext/imp_elementaltv.go b/openrtb_ext/imp_elementaltv.go new file mode 100644 index 0000000000..a1f267f971 --- /dev/null +++ b/openrtb_ext/imp_elementaltv.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ExtImpElementalTV struct { + AdUnit string `json:"adunit"` +} diff --git a/openrtb_ext/imp_eskimi.go b/openrtb_ext/imp_eskimi.go new file mode 100644 index 0000000000..cf6922c21d --- /dev/null +++ b/openrtb_ext/imp_eskimi.go @@ -0,0 +1,14 @@ +package openrtb_ext + +// ExtImpEskimi defines the contract for bidrequest.imp[i].ext.prebid.bidder.eskimi. +// COPPA and test flags are handled by PBS core via request.regs.coppa / request.test; +// they are not duplicated as bidder params. +type ExtImpEskimi struct { + PlacementID int64 `json:"placementId"` + BidFloor float64 `json:"bidFloor,omitempty"` + BidFloorCur string `json:"bidFloorCur,omitempty"` + Bcat []string `json:"bcat,omitempty"` + Badv []string `json:"badv,omitempty"` + Bapp []string `json:"bapp,omitempty"` + Battr []int64 `json:"battr,omitempty"` +} diff --git a/openrtb_ext/imp_ezoic.go b/openrtb_ext/imp_ezoic.go new file mode 100644 index 0000000000..609650ad5e --- /dev/null +++ b/openrtb_ext/imp_ezoic.go @@ -0,0 +1,8 @@ +package openrtb_ext + +// ExtImpEzoic defines the contract for bidrequest.imp[i].ext.prebid.bidder.ezoic. +// Ezoic eligibility is resolved server-side from site.domain, so no params are +// required; placementId is an optional onboarding-assigned identifier. +type ExtImpEzoic struct { + PlacementID string `json:"placementId,omitempty"` +} diff --git a/openrtb_ext/imp_freewheelssp.go b/openrtb_ext/imp_freewheelssp.go index 5ed1f62609..78040d7bd6 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/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type ImpExtFreewheelSSP struct { diff --git a/openrtb_ext/imp_goldbach.go b/openrtb_ext/imp_goldbach.go index 238ef2ff2e..512b7883e8 100644 --- a/openrtb_ext/imp_goldbach.go +++ b/openrtb_ext/imp_goldbach.go @@ -3,7 +3,7 @@ package openrtb_ext import ( "fmt" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type ImpExtGoldbach struct { diff --git a/openrtb_ext/imp_gothamads.go b/openrtb_ext/imp_intenze.go similarity index 68% rename from openrtb_ext/imp_gothamads.go rename to openrtb_ext/imp_intenze.go index fb945fbba6..991c4817ac 100644 --- a/openrtb_ext/imp_gothamads.go +++ b/openrtb_ext/imp_intenze.go @@ -1,5 +1,5 @@ package openrtb_ext -type ExtGothamAds struct { +type ExtIntenze struct { AccountID string `json:"accountId"` } diff --git a/openrtb_ext/imp_intertech.go b/openrtb_ext/imp_intertech.go deleted file mode 100644 index 7c0bc955c5..0000000000 --- a/openrtb_ext/imp_intertech.go +++ /dev/null @@ -1,6 +0,0 @@ -package openrtb_ext - -type ExtImpIntertech struct { - PageID int `json:"page_id"` - ImpID int `json:"imp_id"` -} diff --git a/openrtb_ext/imp_missena.go b/openrtb_ext/imp_missena.go index 6884209b7f..ac4a722341 100644 --- a/openrtb_ext/imp_missena.go +++ b/openrtb_ext/imp_missena.go @@ -4,6 +4,6 @@ type ExtImpMissena struct { APIKey string `json:"apiKey"` Formats []string `json:"formats"` Placement string `json:"placement"` - TestMode string `json:"test"` + Sample string `json:"sample"` Settings map[string]any `json:"settings,omitempty"` } diff --git a/openrtb_ext/imp_nativo.go b/openrtb_ext/imp_nativo.go new file mode 100644 index 0000000000..b4623bc5e8 --- /dev/null +++ b/openrtb_ext/imp_nativo.go @@ -0,0 +1,7 @@ +package openrtb_ext + +import "github.com/prebid/prebid-server/v4/util/jsonutil" + +type ImpExtNativo struct { + PlacementID jsonutil.StringInt `json:"placementId"` +} diff --git a/openrtb_ext/imp_pixfuture.go b/openrtb_ext/imp_pixfuture.go new file mode 100644 index 0000000000..be8bf36531 --- /dev/null +++ b/openrtb_ext/imp_pixfuture.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ImpExtPixfuture struct { + PixID string `json:"pix_id"` +} diff --git a/openrtb_ext/imp_proxistore.go b/openrtb_ext/imp_proxistore.go new file mode 100644 index 0000000000..6c6b5bd5f0 --- /dev/null +++ b/openrtb_ext/imp_proxistore.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ExtImpProxistore struct { + Website string `json:"website"` + Language string `json:"language"` +} diff --git a/openrtb_ext/imp_pulsepoint.go b/openrtb_ext/imp_pulsepoint.go index a372e3765c..9be3a36941 100644 --- a/openrtb_ext/imp_pulsepoint.go +++ b/openrtb_ext/imp_pulsepoint.go @@ -1,7 +1,7 @@ package openrtb_ext import ( - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) // ExtImpPulsePoint defines the json spec for bidrequest.imp[i].ext.prebid.bidder.pulsepoint diff --git a/openrtb_ext/imp_relevantdigital.go b/openrtb_ext/imp_relevantdigital.go index ec250557c2..ccd5c201f4 100644 --- a/openrtb_ext/imp_relevantdigital.go +++ b/openrtb_ext/imp_relevantdigital.go @@ -1,8 +1,9 @@ package openrtb_ext type ExtRelevantDigital struct { - AccountId string `json:"accountId"` - PlacementId string `json:"placementId"` - Host string `json:"pbsHost"` - PbsBufferMs int `json:"pbsBufferMs"` + AccountId string `json:"accountId"` + PlacementId string `json:"placementId"` + Host string `json:"pbsHost"` + PbsBufferMs int `json:"pbsBufferMs"` + UseSourceBidderCode bool `json:"useSourceBidderCode,omitempty"` } diff --git a/openrtb_ext/imp_rtbstack.go b/openrtb_ext/imp_rtbstack.go new file mode 100644 index 0000000000..d98e1b69bd --- /dev/null +++ b/openrtb_ext/imp_rtbstack.go @@ -0,0 +1,7 @@ +package openrtb_ext + +type ExtImpRTBStack struct { + Route string `json:"route"` + TagId string `json:"tagId"` + CustomParams map[string]interface{} `json:"customParams,omitempty"` +} diff --git a/openrtb_ext/imp_scalibur.go b/openrtb_ext/imp_scalibur.go new file mode 100644 index 0000000000..9a0ff7902f --- /dev/null +++ b/openrtb_ext/imp_scalibur.go @@ -0,0 +1,11 @@ +package openrtb_ext + +type ExtImpScalibur struct { + PlacementID string `json:"placementId"` // required + BidFloor *float64 `json:"bidfloor,omitempty"` // optional, used as fallback + BidFloorCur string `json:"bidfloorcur,omitempty"` // optional, defaults to USD if empty +} + +type ExtRequestScalibur struct { + IsDebug int `json:"isDebug,omitempty"` +} diff --git a/openrtb_ext/imp_screencore.go b/openrtb_ext/imp_screencore.go deleted file mode 100644 index 5a3fa1c39f..0000000000 --- a/openrtb_ext/imp_screencore.go +++ /dev/null @@ -1,6 +0,0 @@ -package openrtb_ext - -type ExtScreencore struct { - AccountID string `json:"accountId"` - PlacementID string `json:"placementId"` -} diff --git a/openrtb_ext/imp_seedtag.go b/openrtb_ext/imp_seedtag.go index 825595dd29..4a235cb986 100644 --- a/openrtb_ext/imp_seedtag.go +++ b/openrtb_ext/imp_seedtag.go @@ -1,5 +1,7 @@ package openrtb_ext type ImpExtSeedtag struct { - AdUnitID string `json:"adUnitId"` + AdUnitID string `json:"adUnitId,omitempty"` + PublisherID string `json:"publisherId,omitempty"` + IntegrationType string `json:"integrationType,omitempty"` } diff --git a/openrtb_ext/imp_stackadapt.go b/openrtb_ext/imp_stackadapt.go new file mode 100644 index 0000000000..930899c2a2 --- /dev/null +++ b/openrtb_ext/imp_stackadapt.go @@ -0,0 +1,13 @@ +package openrtb_ext + +type ExtImpStackAdapt struct { + PublisherId string `json:"publisherId"` + SupplyId string `json:"supplyId"` + PlacementId *string `json:"placementId,omitempty"` + Banner *ExtImpStackAdaptBanner `json:"banner,omitempty"` + BidFloor float64 `json:"bidfloor,omitempty"` +} + +type ExtImpStackAdaptBanner struct { + ExpDir []int `json:"expdir,omitempty"` +} diff --git a/openrtb_ext/imp_synapseHX.go b/openrtb_ext/imp_synapseHX.go new file mode 100644 index 0000000000..5cc209fdb5 --- /dev/null +++ b/openrtb_ext/imp_synapseHX.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ExtImpSynapseHX struct { + TenantID string `json:"tenantId"` +} diff --git a/openrtb_ext/imp_tadvertisingblis.go b/openrtb_ext/imp_tadvertisingblis.go new file mode 100644 index 0000000000..dee8d26031 --- /dev/null +++ b/openrtb_ext/imp_tadvertisingblis.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ImpExtTadvertising struct { + PublisherId string `json:"publisherId"` +} diff --git a/openrtb_ext/imp_targetvideo.go b/openrtb_ext/imp_targetvideo.go new file mode 100644 index 0000000000..c13b8a42aa --- /dev/null +++ b/openrtb_ext/imp_targetvideo.go @@ -0,0 +1,8 @@ +package openrtb_ext + +import "github.com/prebid/prebid-server/v4/util/jsonutil" + +// ExtImpTargetVideo defines the contract for bidrequest.imp[i].ext.prebid.bidder.targetVideo +type ExtImpTargetVideo struct { + PlacementId jsonutil.StringInt `json:"placementId,omitempty"` +} diff --git a/openrtb_ext/imp_teal.go b/openrtb_ext/imp_teal.go new file mode 100644 index 0000000000..9f961c33b1 --- /dev/null +++ b/openrtb_ext/imp_teal.go @@ -0,0 +1,17 @@ +package openrtb_ext + +// ExtImpTeal carries the per-imp Teal bidder-slot params. +// +// Account is required. The first valid imp's account is propagated to +// BidRequest.Site.Publisher.ID (and BidRequest.App.Publisher.ID, when present). +// All imps in a request must use the same account: a later imp whose account +// differs is rejected with a BadInput error and dropped. +// +// Placement is optional. When present and non-blank, the adapter injects +// imp.ext.prebid.storedrequest.id = placement on a per-imp basis. Pointer-typed +// to distinguish absent (nil) from present-but-blank (non-nil → validation +// failure). +type ExtImpTeal struct { + Account string `json:"account"` + Placement *string `json:"placement,omitempty"` +} diff --git a/openrtb_ext/imp_trustx.go b/openrtb_ext/imp_trustx.go new file mode 100644 index 0000000000..8187f91a2c --- /dev/null +++ b/openrtb_ext/imp_trustx.go @@ -0,0 +1,9 @@ +package openrtb_ext + +import "encoding/json" + +// ExtImpTrustX defines the contract for bidrequest.imp[i].ext.prebid.bidder.trustx +type ExtImpTrustX struct { + Uid int `json:"uid"` + Keywords json.RawMessage `json:"keywords,omitempty"` +} diff --git a/openrtb_ext/multibid_test.go b/openrtb_ext/multibid_test.go index 5a55265311..9e8de09d9e 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/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/regs_test.go b/openrtb_ext/regs_test.go index 064282c1f3..ed998054ac 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/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/request.go b/openrtb_ext/request.go index 7f8978e6eb..6d51d42145 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/v3/util/jsonutil" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/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 92f148db40..b0c09f6c55 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/v3/util/jsonutil" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/request_wrapper.go b/openrtb_ext/request_wrapper.go index 7b73d31867..52ed2ba91f 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/v3/util/jsonutil" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) // RequestWrapper wraps the OpenRTB request to provide a storage location for unmarshalled ext fields, so they diff --git a/openrtb_ext/request_wrapper_test.go b/openrtb_ext/request_wrapper_test.go index e4c14b6031..ca332679b0 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/v3/errortypes" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/site_test.go b/openrtb_ext/site_test.go index e06c0e67bd..e76e06c8c5 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/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/supplyChain.go b/openrtb_ext/supplyChain.go index 0051d647ff..b8abdb4c32 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/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) func cloneSupplyChain(schain *openrtb2.SupplyChain) *openrtb2.SupplyChain { diff --git a/openrtb_ext/supplyChain_test.go b/openrtb_ext/supplyChain_test.go index 1adfaf8f62..86c2741dac 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/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/ortb/clone.go b/ortb/clone.go index 07eaf2886b..8a0f505acd 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/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) func CloneDataSlice(s []openrtb2.Data) []openrtb2.Data { diff --git a/ortb/clone_test.go b/ortb/clone_test.go index 14bdc0bb19..5f86b5121f 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/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/ortb/default.go b/ortb/default.go index f6cc979045..43e787f39b 100644 --- a/ortb/default.go +++ b/ortb/default.go @@ -1,8 +1,8 @@ package ortb import ( - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) const ( diff --git a/ortb/default_test.go b/ortb/default_test.go index b03f546fd4..cb6af876b5 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/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/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" ) func TestSetDefaults(t *testing.T) { diff --git a/ortb/request_validator.go b/ortb/request_validator.go index e959caa934..57ba91ff2c 100644 --- a/ortb/request_validator.go +++ b/ortb/request_validator.go @@ -4,9 +4,9 @@ import ( "encoding/json" "fmt" - "github.com/prebid/prebid-server/v3/errortypes" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/stored_responses" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/stored_responses" ) type ValidationConfig struct { diff --git a/ortb/request_validator_banner.go b/ortb/request_validator_banner.go index fea68121a9..c4cf9a2be0 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 e131c32e98..a028305460 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/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/ortb/request_validator_native.go b/ortb/request_validator_native.go index 1209a13913..7d6ff74af8 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/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/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 c2b6ea3c7b..4c548a7cca 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/v3/errortypes" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/ortb/request_validator_video_test.go b/ortb/request_validator_video_test.go index 3d579e2c77..c8f8e4e9bc 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/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/pbs/usersync.go b/pbs/usersync.go index 2a88ecc7b9..d3cc12a0aa 100644 --- a/pbs/usersync.go +++ b/pbs/usersync.go @@ -11,9 +11,9 @@ import ( "strings" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/usersync" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/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 adc57b97ad..07548cc53e 100644 --- a/prebid_cache_client/client.go +++ b/prebid_cache_client/client.go @@ -12,9 +12,9 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" "github.com/buger/jsonparser" "golang.org/x/net/context/ctxhttp" diff --git a/prebid_cache_client/client_test.go b/prebid_cache_client/client_test.go index 31fc05d30b..1b6e146992 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/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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + metricsConf "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/privacy/activitycontrol.go b/privacy/activitycontrol.go index 674d751988..4f3d5b1a51 100644 --- a/privacy/activitycontrol.go +++ b/privacy/activitycontrol.go @@ -1,8 +1,8 @@ package privacy import ( - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) type ActivityResult int diff --git a/privacy/activitycontrol_test.go b/privacy/activitycontrol_test.go index add20ad2c3..8a8d6a03c6 100644 --- a/privacy/activitycontrol_test.go +++ b/privacy/activitycontrol_test.go @@ -3,9 +3,9 @@ package privacy import ( "testing" - "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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/privacy/ccpa/consentwriter_test.go b/privacy/ccpa/consentwriter_test.go index 6d0b89e24c..e087cd13ac 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/privacy/ccpa/parsedpolicy.go b/privacy/ccpa/parsedpolicy.go index 98b04a1632..c442bd4d23 100644 --- a/privacy/ccpa/parsedpolicy.go +++ b/privacy/ccpa/parsedpolicy.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v4/errortypes" ) const ( diff --git a/privacy/ccpa/policy.go b/privacy/ccpa/policy.go index b4841a174f..a32c41cc34 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/v3/errortypes" - "github.com/prebid/prebid-server/v3/openrtb_ext" - gppPolicy "github.com/prebid/prebid-server/v3/privacy/gpp" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + gppPolicy "github.com/prebid/prebid-server/v4/privacy/gpp" ) // Policy represents the CCPA regulatory information from an OpenRTB bid request. diff --git a/privacy/ccpa/policy_test.go b/privacy/ccpa/policy_test.go index 89bb2ccf04..5274c566f4 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/privacy/lmt/ios.go b/privacy/lmt/ios.go index 7778a02d0a..ccfa409f05 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/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/iosutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/iosutil" ) var ( diff --git a/privacy/lmt/ios_test.go b/privacy/lmt/ios_test.go index 42636759eb..e0c98c5b61 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/v3/util/iosutil" + "github.com/prebid/prebid-server/v4/util/iosutil" "github.com/stretchr/testify/assert" ) diff --git a/privacy/rule_condition_test.go b/privacy/rule_condition_test.go index 97bdeef35f..aaa6ac51f4 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/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/privacy/scrubber.go b/privacy/scrubber.go index 8f4a9b103f..fbda5b88c6 100644 --- a/privacy/scrubber.go +++ b/privacy/scrubber.go @@ -4,12 +4,12 @@ import ( "encoding/json" "net" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/iputil" ) type IPConf struct { diff --git a/privacy/scrubber_test.go b/privacy/scrubber_test.go index ccb065bccb..0c8813b5d5 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/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/privacysandbox/topics.go b/privacysandbox/topics.go index 3ed620b4bd..8483321315 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/v3/errortypes" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type Topic struct { diff --git a/privacysandbox/topics_test.go b/privacysandbox/topics_test.go index 73d5ef0c12..64c1de0ec8 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/v3/errortypes" + "github.com/prebid/prebid-server/v4/errortypes" "github.com/stretchr/testify/assert" ) diff --git a/router/admin.go b/router/admin.go index 3053cebe29..0d34b11162 100644 --- a/router/admin.go +++ b/router/admin.go @@ -6,9 +6,9 @@ import ( "time" delta "github.com/grafana/pyroscope-go/godeltaprof/http/pprof" - "github.com/prebid/prebid-server/v3/currency" - "github.com/prebid/prebid-server/v3/endpoints" - "github.com/prebid/prebid-server/v3/version" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/endpoints" + "github.com/prebid/prebid-server/v4/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 0a4d147d90..6dee25a525 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/v3/config" - "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/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 2ac8f36ae3..2cfb144802 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/v3/config" - "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" "github.com/stretchr/testify/assert" ) diff --git a/router/router.go b/router/router.go index d0bbef1aa2..b82b837eba 100644 --- a/router/router.go +++ b/router/router.go @@ -12,36 +12,36 @@ import ( "time" 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/logger" - "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" + analyticsBuild "github.com/prebid/prebid-server/v4/analytics/build" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/currency" + "github.com/prebid/prebid-server/v4/endpoints" + "github.com/prebid/prebid-server/v4/endpoints/events" + infoEndpoints "github.com/prebid/prebid-server/v4/endpoints/info" + "github.com/prebid/prebid-server/v4/endpoints/openrtb2" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/exchange" + "github.com/prebid/prebid-server/v4/experiment/adscert" + "github.com/prebid/prebid-server/v4/floors" + "github.com/prebid/prebid-server/v4/gdpr" + "github.com/prebid/prebid-server/v4/hooks" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/macros" + "github.com/prebid/prebid-server/v4/metrics" + metricsConf "github.com/prebid/prebid-server/v4/metrics/config" + "github.com/prebid/prebid-server/v4/modules" + "github.com/prebid/prebid-server/v4/modules/moduledeps" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/ortb" + "github.com/prebid/prebid-server/v4/pbs" + pbc "github.com/prebid/prebid-server/v4/prebid_cache_client" + "github.com/prebid/prebid-server/v4/router/aspects" + "github.com/prebid/prebid-server/v4/server/ssl" + storedRequestsConf "github.com/prebid/prebid-server/v4/stored_requests/config" + "github.com/prebid/prebid-server/v4/usersync" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/uuidutil" + "github.com/prebid/prebid-server/v4/version" _ "github.com/go-sql-driver/mysql" "github.com/julienschmidt/httprouter" @@ -128,15 +128,14 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R Router: httprouter.New(), } - // For bid processing, we need both the hardcoded certificates and the certificates found in container's - // local file system - certPool, certPoolCreateErr := ssl.CreateCertPool(cfg.CertsUseSystem) + certPool, certPoolCreateErr := ssl.CreateCertPool() if certPoolCreateErr != nil { logger.Infof("Could not load root certificates: %s \n", certPoolCreateErr.Error()) } + // load optional PEM certificate files var readCertErr error - certPool, readCertErr = ssl.AppendPEMFileToRootCAPool(certPool, cfg.PemCertsFile) + certPool, readCertErr = ssl.AppendPEMFileToCertPool(certPool, cfg.PemCertsFile) if readCertErr != nil { logger.Infof("Could not read certificates file: %s \n", readCertErr.Error()) } @@ -221,9 +220,6 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R analyticsRunner := analyticsBuild.New(&cfg.Analytics) - // register the analytics runner for shutdown - r.shutdowns = append(r.shutdowns, shutdown, analyticsRunner.Shutdown, shutdownModules.Shutdown) - paramsValidator, err := openrtb_ext.NewBidderParamsValidator(schemaDirectory) if err != nil { logger.Fatalf("Failed to create the bidder params validator. %v", err) @@ -236,9 +232,16 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R gvlVendorIDs := cfg.BidderInfos.ToGVLVendorIDMap() vendorListFetcher := gdpr.NewVendorListFetcher(context.Background(), cfg.GDPR, generalHttpClient, r.MetricsEngine, gdpr.VendorListURLMaker) - gdprPermsBuilder := gdpr.NewPermissionsBuilder(cfg.GDPR, gvlVendorIDs, vendorListFetcher, r.MetricsEngine) + liveGVLVendorIDs := gdpr.NewLiveGVLVendorIDs() + refreshInterval := time.Duration(cfg.GDPR.LiveGVLRefreshInterval) * time.Second + gvlVendorIDTask := gdpr.NewGVLVendorIDTickerTask(refreshInterval, generalHttpClient, gdpr.VendorListURLMaker, liveGVLVendorIDs, r.MetricsEngine) + gvlVendorIDTask.Start() + gdprPermsBuilder := gdpr.NewPermissionsBuilder(cfg.GDPR, gvlVendorIDs, liveGVLVendorIDs, vendorListFetcher, r.MetricsEngine) tcf2CfgBuilder := gdpr.NewTCF2Config + // register the analytics runner, modules and live GVL Vendor ID ticker task for shutdown + r.shutdowns = append(r.shutdowns, shutdown, analyticsRunner.Shutdown, shutdownModules.Shutdown, gvlVendorIDTask.Stop) + cacheClient := pbc.NewClient(cacheHttpClient, &cfg.CacheURL, &cfg.ExtCacheURL, r.MetricsEngine) adapters, singleFormatAdapters, adaptersErrs := exchange.BuildAdapters(generalHttpClient, cfg, cfg.BidderInfos, r.MetricsEngine) diff --git a/router/router_test.go b/router/router_test.go index 2566744609..6023f7ae05 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/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/rules/schema_functions.go b/rules/schema_functions.go index 32a5c6a4b5..5ed668811c 100644 --- a/rules/schema_functions.go +++ b/rules/schema_functions.go @@ -7,10 +7,10 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "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/util/randomutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/randomutil" ) const ( diff --git a/rules/schema_functions_test.go b/rules/schema_functions_test.go index 46b03dc380..033fb1ef9d 100644 --- a/rules/schema_functions_test.go +++ b/rules/schema_functions_test.go @@ -7,10 +7,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "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/prebid/prebid-server/v3/util/randomutil" + "github.com/prebid/prebid-server/v4/errortypes" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/randomutil" "github.com/stretchr/testify/assert" ) diff --git a/schain/schain.go b/schain/schain.go index cdd1e14449..e88d47c143 100644 --- a/schain/schain.go +++ b/schain/schain.go @@ -5,7 +5,7 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // BidderToPrebidSChains organizes the ORTB 2.5 multiple root schain nodes into a map of schain nodes by bidder diff --git a/schain/schain_test.go b/schain/schain_test.go index f112c9ec7e..040522d8ff 100644 --- a/schain/schain_test.go +++ b/schain/schain_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/schain/schainwriter.go b/schain/schainwriter.go index 37b62c993f..36a9810a1e 100644 --- a/schain/schainwriter.go +++ b/schain/schainwriter.go @@ -2,7 +2,7 @@ package schain import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // NewSChainWriter creates an ORTB 2.5 schain writer instance diff --git a/schain/schainwriter_test.go b/schain/schainwriter_test.go index 69fda95907..ef1e02e52a 100644 --- a/schain/schainwriter_test.go +++ b/schain/schainwriter_test.go @@ -4,8 +4,8 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" "github.com/stretchr/testify/assert" diff --git a/server/listener.go b/server/listener.go index ece1a6ec3d..3bdeb176fe 100644 --- a/server/listener.go +++ b/server/listener.go @@ -5,8 +5,8 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" ) // monitorableListener tracks any opened connections in the metrics. diff --git a/server/listener_test.go b/server/listener_test.go index 293890a1e1..b54ae35ded 100644 --- a/server/listener_test.go +++ b/server/listener_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" gometrics "github.com/rcrowley/go-metrics" ) diff --git a/server/prometheus.go b/server/prometheus.go index 332eebdd1c..2ddcc55a70 100644 --- a/server/prometheus.go +++ b/server/prometheus.go @@ -5,9 +5,9 @@ import ( "net/http" "strconv" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - metricsconfig "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + metricsconfig "github.com/prebid/prebid-server/v4/metrics/config" "github.com/prometheus/client_golang/prometheus/promhttp" ) diff --git a/server/server.go b/server/server.go index 6dddaee4ff..b0b4a9f93e 100644 --- a/server/server.go +++ b/server/server.go @@ -12,11 +12,11 @@ import ( "time" "github.com/NYTimes/gziphandler" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/metrics" - metricsconfig "github.com/prebid/prebid-server/v3/metrics/config" - mspPlugin "github.com/prebid/prebid-server/v3/msp/plugin" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" + metricsconfig "github.com/prebid/prebid-server/v4/metrics/config" + mspPlugin "github.com/prebid/prebid-server/v4/msp/plugin" ) // Listen blocks forever, serving PBS requests on the given port. This will block forever, until the process is shut down. diff --git a/server/server_test.go b/server/server_test.go index 6d2a3335e3..389b9884dd 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -9,8 +9,8 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v3/config" - metricsconfig "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v4/config" + metricsconfig "github.com/prebid/prebid-server/v4/metrics/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/server/ssl/ssl.go b/server/ssl/ssl.go index ee754ed66d..6a69f6de2e 100644 --- a/server/ssl/ssl.go +++ b/server/ssl/ssl.go @@ -2,3664 +2,30 @@ package ssl import ( "crypto/x509" - "errors" "fmt" "os" ) -// from https://medium.com/@kelseyhightower/optimizing-docker-images-for-static-binaries-b5696e26eb07 - -var ( - ErrLoadEmbeddedCerts = errors.New("failed to load embedded certs") -) - -func CreateCertPool(useSystem bool) (*x509.CertPool, error) { - if useSystem { - return x509.SystemCertPool() - } - - return createCertPoolFromEmbedded() +func CreateCertPool() (*x509.CertPool, error) { + return x509.SystemCertPool() } -func createCertPoolFromEmbedded() (*x509.CertPool, error) { - pool := x509.NewCertPool() - - if ok := pool.AppendCertsFromPEM(pemCerts); !ok { - return pool, ErrLoadEmbeddedCerts - } - - return pool, nil -} - -// Appends certificates to the `x509.CertPool` from a `.pem` private local file. On many Linux -// systems, /etc/ssl/cert.pem will contain the system wide set but in our case, we'll pull -// the certificate file path from the `Configuration` struct -func AppendPEMFileToRootCAPool(certPool *x509.CertPool, pemFileName string) (*x509.CertPool, error) { +// AppendPEMFileToCertPool appends certificates from a PEM file to the provided certificate pool. +// This is a helper method intended for use in main startup code to append specific certificates +// to the system certificate pool. +func AppendPEMFileToCertPool(certPool *x509.CertPool, pemFileName string) (*x509.CertPool, error) { if certPool == nil { certPool = x509.NewCertPool() } + if pemFileName != "" { - //read file and place it's contents in `pemCerts` pemCerts, err := os.ReadFile(pemFileName) if err != nil { return certPool, fmt.Errorf("Failed to read file %s: %v", pemFileName, err) } - //`pemCerts` has been obtained, append to certPool certPool.AppendCertsFromPEM(pemCerts) } + return certPool, nil } - -var pemCerts = []byte(` ------BEGIN CERTIFICATE----- -MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE -AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw -CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ -BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND -VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb -qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY -HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo -G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA -lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr -IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ -0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH -k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 -4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO -m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa -cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl -uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI -KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls -ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG -AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 -VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT -VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG -CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA -cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA -QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA -7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA -cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA -QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA -czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu -aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt -aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud -DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF -BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp -D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU -JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m -AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD -vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms -tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH -7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h -I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA -h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF -d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H -pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx -CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ -WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ -BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG -Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ -yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf -BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz -WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF -tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z -374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC -IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL -mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 -wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS -MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 -ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet -UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H -YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 -LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD -nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 -RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM -LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf -77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N -JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm -fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp -6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp -1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B -9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok -RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv -uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw -CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw -FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S -Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 -MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL -DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS -QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH -sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK -Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu -SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC -MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy -v+c= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV -BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk -YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV -BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN -MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF -UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD -VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v -dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj -cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q -yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH -2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX -H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL -zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR -p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz -W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/ -SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn -LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3 -n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B -u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj -o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC -AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L -9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej -rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK -pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0 -vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq -OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ -/zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9 -2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI -+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2 -MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo -tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE -BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w -MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 -IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC -SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 -ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv -UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX -4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 -KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ -gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb -rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ -51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F -be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe -KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F -v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn -fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 -jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz -ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt -ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL -e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 -jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz -WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V -SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j -pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX -X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok -fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R -K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU -ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU -LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT -LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP -Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr -ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL -MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 -yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr -VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ -nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG -XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj -vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt -Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g -N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC -nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y -YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua -kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL -QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp -6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG -yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i -QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO -tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu -QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ -Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u -olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 -x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz -dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG -A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U -cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf -qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ -JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ -+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS -s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 -HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 -70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG -V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S -qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S -5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia -C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX -OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE -FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 -KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B -8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ -MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc -0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ -u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF -u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH -YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 -GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO -RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e -KeC2uAloGRwYQw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC -VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ -cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ -BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt -VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D -0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 -ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G -A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs -aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I -flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj -ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM -9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw -IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 -VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L -93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm -jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA -A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI -U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs -N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv -o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU -5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy -rqXRfboQnoZsG4q5WTP468SQvvG5 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK -gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ -W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg -1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K -8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r -2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me -z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR -8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj -mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz -7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 -+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI -0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB -Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm -UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 -LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY -+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS -k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl -7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm -btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl -urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ -fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 -n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE -76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H -9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT -4PsJYGw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl -ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr -ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr -BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM -YyRIHN8wfdVoOw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi -9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk -M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB -MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw -CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW -1KyLa2tJElMzrdfkviT8tQp21KW8EA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE -AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG -EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM -FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC -REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp -Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM -VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ -SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ -4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L -cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi -eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG -A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 -DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j -vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP -DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc -maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D -lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv -KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w -LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w -CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0 -MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF -Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI -zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X -tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4 -AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2 -KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD -aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu -CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo -9H1/IISpQuQo ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM -MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx -MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00 -MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD -QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN -BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z -4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv -Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ -kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs -GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln -nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh -3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD -0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy -geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8 -ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB -c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI -pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU -dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB -DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS -4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs -o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ -qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw -xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM -rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4 -AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR -0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY -o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5 -dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE -oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 -MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 -thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM -cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG -L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i -NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h -X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b -m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy -Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja -EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T -KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF -6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh -OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc -tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd -IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j -b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC -AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw -ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m -iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF -Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ -hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P -Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE -EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV -1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t -CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR -5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw -f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 -ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK -GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU -MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI -T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz -MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF -SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh -bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z -xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ -spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5 -58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR -at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll -5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq -nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK -V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/ -pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO -z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn -jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+ -WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF -7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 -YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli -awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u -+2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88 -X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN -SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo -P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI -+pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz -znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9 -eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2 -YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy -r/6zcCwupvI= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw -CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ -VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy -MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ -TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS -b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B -IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+ -+kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK -sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA -94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B -43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX -DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y -ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy -VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr -mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr -IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK -mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu -XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy -dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye -jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 -BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 -DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 -9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx -jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 -Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz -ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS -R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr -6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV -L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 -1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx -MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ -QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB -arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr -Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi -FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS -P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN -9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz -uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h -9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s -A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t -OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo -+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 -KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 -DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us -H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ -I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 -5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h -3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz -Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y -ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E -N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 -tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX -0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c -/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X -KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY -zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS -O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D -34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP -K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv -Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj -QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV -cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS -IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 -HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa -O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv -033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u -dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE -kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 -3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD -u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq -4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV -BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu -MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy -MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx -EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw -ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe -NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH -PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I -x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe -QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR -yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO -QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 -H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ -QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD -i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs -nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 -rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI -hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM -tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf -GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb -lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka -+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal -TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i -nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 -gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr -G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os -zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x -L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD -TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y -aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx -MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j -aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP -T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 -sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL -TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 -/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp -7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz -EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt -hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP -a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot -aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg -TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV -PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv -cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL -tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd -BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB -ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT -ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL -jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS -ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy -P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 -xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d -Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN -5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe -/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z -AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ -5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB -gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV -BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw -MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl -YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P -RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 -UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI -2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 -Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp -+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ -DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O -nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW -/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g -PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u -QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY -SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv -IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 -zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd -BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB -ZQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT -IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw -MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy -ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N -T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR -FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J -cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW -BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm -fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv -GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB -hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV -BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT -EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR -6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X -pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC -9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV -/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf -Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z -+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w -qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah -SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC -u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf -Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq -crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E -FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl -wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM -4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV -2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna -FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ -CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK -boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke -jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL -S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb -QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl -0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB -NVOFBkpdn627G190 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw -CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu -bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ -BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s -eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK -+IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 -QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 -hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm -ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG -BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw -PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy -dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 -YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 -1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT -vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed -aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 -1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 -r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 -cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ -wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ -6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA -2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH -Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR -eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB -/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u -d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr -PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d -8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi -1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd -rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di -taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 -lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj -yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn -Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy -yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n -wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 -OV+KmalBWQewLK8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV -BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X -DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ -BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 -QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny -gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw -zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q -130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 -JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw -ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT -AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj -AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG -9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h -bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc -fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu -HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w -t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw -WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw -WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw -MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x -MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD -VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX -BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO -ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M -CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu -I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm -TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh -C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf -ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz -IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT -Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k -JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 -hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB -GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of -1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov -L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo -dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr -aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq -hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L -6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG -HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 -0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB -lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi -o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 -gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v -faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 -Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh -jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw -3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw -CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw -JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT -EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 -WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT -LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX -BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE -KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm -Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 -EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J -UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn -nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM -MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D -ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU -cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 -WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg -Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw -IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH -UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM -TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU -BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM -kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x -AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV -HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y -sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL -I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 -J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY -VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB -gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu -QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG -A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz -OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ -VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 -b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA -DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn -0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB -OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE -fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E -Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m -o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i -sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW -OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez -Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS -adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n -3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ -F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf -CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 -XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm -djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ -WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb -AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq -P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko -b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj -XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P -5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi -DrW5viSP ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6 -MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu -MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV -BAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwHhcNMTgwMzE2MTIxMDEzWhcNNDMw -MzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEg -U3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRo -b3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZ -n0EGze2jusDbCSzBfN8pfktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/q -p1x4EaTByIVcJdPTsuclzxFUl6s1wB52HO8AU5853BSlLCIls3Jy/I2z5T4IHhQq -NwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2fJmItdUDmj0VDT06qKhF -8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGtg/BKEiJ3 -HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGa -mqi4NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi -7VdNIuJGmj8PkTQkfVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSF -ytKAQd8FqKPVhJBPC/PgP5sZ0jeJP/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0P -qafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSYnjYJdmZm/Bo/6khUHL4wvYBQ -v3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHKHRzQ+8S1h9E6 -Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1 -vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQAD -ggIBAEii1QALLtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4 -WxmB82M+w85bj/UvXgF2Ez8sALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvo -zMrnadyHncI013nR03e4qllY/p0m+jiGPp2Kh2RX5Rc64vmNueMzeMGQ2Ljdt4NR -5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8CYyqOhNf6DR5UMEQ -GfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA4kZf -5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq -0Uc9NneoWWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7D -P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM -qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP -0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf -E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMw -TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t -bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNa -Fw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv -cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDEw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLxeP0C -flfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJE -hRGnSjot6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggq -hkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg -2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liWpDVfG2XqYZpwI7UNo5uS -Um9poIyNStDuiw7LR47QjRE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMw -TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t -bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRa -Fw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv -cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDIw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/MMDAL -j2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmU -v4RDsNuESgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggq -hkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/n -ich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs73u1Z/GtMMH9ZzkXpc2AV -mkzw5l4lIhVtwodZ0LKOag== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQEL -BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi -Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1 -NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t -U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt -MDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45FtnYSk -YZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslh -suitQDy6uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0al -DrJLpA6lfO741GIDuZNqihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3Oj -WiE260f6GBfZumbCk6SP/F2krfxQapWsvCQz0b2If4b19bJzKo98rwjyGpg/qYFl -P8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/cZip8UlF1y5mO6D1cv547 -KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTifBSeolz7p -UcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/ -kQO9lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JO -Hg9O5j9ZpSPcPYeoKFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkB -Ea801M/XrmLTBQe0MXXgDW1XT2mH+VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6U -CBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm45P3luG0wDQYJ -KoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6 -NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQ -nmhUQo8mUuJM3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+ -QgvfKNmwrZggvkN80V4aCRckjXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2v -trV0KnahP/t1MJ+UXjulYPPLXAziDslg+MkfFoom3ecnf+slpoq9uC02EJqxWE2a -aE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/WNyVntHKLr4W96ioD -j8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+o/E4 -Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0w -lREQKC6/oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHn -YfkUyq+Dj7+vsQpZXdxc1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVoc -icCMb3SgazNNtQEo/a2tiRc7ppqEvOuM6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQEL -BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi -Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2 -NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t -U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt -MDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3VrCLE -NQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0 -kyI9p+Kx7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1C -rWDaSWqVcN3SAOLMV2MCe5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxz -hkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2WWy09X6GDRl224yW4fKcZgBzqZUPckXk2 -LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rpM9kzXzehxfCrPfp4sOcs -n/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIfhs1w/tku -FT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5 -kQMreyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3 -wNemKfrb3vOTlycEVS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6v -wQcQeKwRoi9C8DfF8rhW3Q5iLc4tVn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs -5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7GxcJXvYXowDQYJ -KoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB -KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3 -+VGXu6TwYofF1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbyme -APnCKfWxkxlSaRosTKCL4BWaMS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3Nyq -pgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xdgSGn2rtO/+YHqP65DSdsu3BaVXoT -6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2OHG1QAk8mGEPej1WF -sQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+NmYWvt -PjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2d -lklyALKrdVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670 -v64fG9PiO/yzcnMcmyiQiRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17O -rg3bhzjlP1v9mxnhMUF6cKojawHhRUzNlM47ni3niAIi9G7oyOzWPPO5std3eqx7 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb -MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow -GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj -YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM -GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua -BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe -3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 -YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR -rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm -ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU -oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF -MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v -QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t -b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF -AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q -GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 -G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi -l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 -smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw -CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS -VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5 -NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG -A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB -BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS -zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0 -QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/ -VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g -PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf -Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l -dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 -c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO -PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW -wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV -dWNbFJWcHwHP2NVypw87 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw -CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS -VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5 -NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG -A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB -BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC -/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD -wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3 -OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g -PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf -Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l -dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 -c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO -PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA -y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb -gfM0agPnIjhQW+0ZT0MW ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha -ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM -HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 -UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 -tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R -ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM -lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp -/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G -A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G -A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj -dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy -MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl -cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js -L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL -BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni -acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 -o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K -zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 -PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y -Johw1+qRzT65ysCQblrGXnRl11z+o+I= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw -NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV -BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn -ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 -3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z -qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR -p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 -HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw -ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea -HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw -Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh -c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E -RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt -dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku -Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp -3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 -nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF -CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na -xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX -KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c -JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP -mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ -wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 -VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ -AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB -AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun -pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC -dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf -fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm -NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx -H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA -n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc -biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp -EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA -bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu -YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB -AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW -BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI -QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I -0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni -lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 -B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv -ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo -IhNzbM8m9Yop5w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg -RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf -Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q -RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD -AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY -JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv -6pZjamVFkpUBtA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB -CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 -nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt -43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P -T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 -gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR -TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw -DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr -hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg -06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF -PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls -YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH -MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI -2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx -1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ -q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz -tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ -vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV -5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY -1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 -NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG -Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 -8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe -pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl -MrY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe -Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw -EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x -IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG -fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO -Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd -BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx -AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ -oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 -sycX ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm -+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW -PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM -xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB -Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 -hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg -EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA -FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec -nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z -eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF -hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 -Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep -+OkuE6N36B9K ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp -Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 -MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ -bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG -ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS -7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp -0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS -B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 -BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ -LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 -DXZDjC5Ty3zfDBeWUA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN -MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT -HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN -NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs -IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ -ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 -2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp -wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM -pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD -nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po -sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx -Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd -Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX -KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe -XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL -tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv -TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN -AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw -GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H -PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF -O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ -REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik -AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv -/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ -p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw -MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF -qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK -ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg -RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y -ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If -xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV -ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO -DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ -jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ -CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi -EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM -fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY -uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK -chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t -9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD -ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 -SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd -+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc -fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa -sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N -cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N -0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie -4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI -r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 -/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm -gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 -MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 -LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp -YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG -A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq -K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe -sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX -MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT -XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ -HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH -4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub -j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo -U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf -zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b -u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ -bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er -fF6adulZkMV8gzURZVE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 -Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW -KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw -NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw -NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy -ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV -BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo -Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 -4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 -KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI -rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi -94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB -sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi -gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo -kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE -vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t -O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua -AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP -9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ -eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m -0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG -A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 -d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu -dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq -RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy -MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD -VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 -L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g -Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi -A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt -ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH -Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC -R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX -hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 -cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs -IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz -dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy -NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu -dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt -dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 -aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T -RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN -cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW -wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 -U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 -jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN -BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ -jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ -Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v -1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R -nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH -VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw -gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL -Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg -MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw -BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 -MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 -c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ -bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg -Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ -2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E -T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j -5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM -C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T -DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX -wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A -2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm -nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 -dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl -N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj -c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS -5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS -Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr -hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ -B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI -AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw -H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ -b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk -2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol -IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk -5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY -n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE -BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ -IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 -MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV -BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w -HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj -Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj -TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u -KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj -qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm -MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 -ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP -zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk -L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC -jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA -HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC -AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg -p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm -DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 -COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry -L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf -JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg -IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io -2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV -09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ -XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq -T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe -MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG -A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw -FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx -MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u -aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq -hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b -RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z -YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3 -QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw -yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+ -BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ -SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH -r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0 -4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me -dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw -q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2 -nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu -H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA -VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC -XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd -6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf -+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi -kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7 -wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB -TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C -MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn -4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I -aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy -qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo -27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w -Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw -TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl -qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH -szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 -Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk -MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 -wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p -aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN -VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID -AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E -FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb -C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe -QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy -h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 -7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J -ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef -MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ -Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT -6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ -0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm -2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb -bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt -nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY -6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu -MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k -RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg -f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV -+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo -dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW -Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa -G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq -gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID -AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E -FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H -vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 -0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC -B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u -NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg -yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev -HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6 -xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR -TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg -JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV -7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl -6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD -VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG -A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw -WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz -IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi -AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G -jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 -4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 -VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm -ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD -VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG -A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw -WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz -IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi -AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi -QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR -HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D -9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 -p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD -VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh -bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw -MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g -UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT -BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx -uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV -HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ -+wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 -bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc -8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke -hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI -KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg -515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO -xwy8p2Fp8fc74SrL+SvzZpA3 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw -MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT -aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ -jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp -xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp -1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG -snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ -U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 -9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B -AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz -yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE -38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP -AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad -DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME -HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 -MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 -RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT -gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm -KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd -QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ -XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o -LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU -RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp -jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK -6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX -mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs -Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH -WD9f ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg -MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh -bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx -MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET -MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI -xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k -ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD -aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw -LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw -1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX -k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 -SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h -bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n -WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY -rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce -MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu -bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN -nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt -Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 -55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj -vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf -cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz -oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp -nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs -pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v -JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R -8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 -5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx -CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD -ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw -MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex -HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq -R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd -yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ -7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 -+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA -MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD -VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy -MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt -c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ -OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG -vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud -316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo -0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE -y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF -zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE -+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN -I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs -x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa -ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC -4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 -7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg -JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti -2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk -pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF -FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt -rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk -ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 -u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP -4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 -N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 -vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh -MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE -YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 -MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo -ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg -MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN -ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA -PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w -wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi -EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY -avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ -YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE -sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h -/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 -IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD -ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy -OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P -TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER -dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf -ReYNnyicsbkqWletNw+vHX/bvZ8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT -EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp -ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz -NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH -EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE -AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD -E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH -/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy -DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh -GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR -tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA -AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX -WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu -9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr -gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo -2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI -4uJEvlz36hz1 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw -CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh -cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v -dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG -A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj -aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg -Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 -KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y -STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD -AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw -SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN -nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs -MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg -Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL -MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl -YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv -b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l -mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE -4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv -a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M -pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw -Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b -LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY -AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB -AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq -E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr -W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ -CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU -X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 -f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja -H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP -JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P -zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt -jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 -/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT -BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 -aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW -xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU -63ZTGI0RmLo= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN -BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl -bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv -b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ -BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj -YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 -MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 -dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg -QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa -jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi -C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep -lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof -TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix -DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k -IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT -N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v -dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG -A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh -ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx -QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA -4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 -AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 -4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C -ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV -9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD -gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 -Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq -NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko -LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc -Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd -ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I -XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI -M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot -9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V -Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea -j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh -X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ -l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf -bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 -pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK -e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 -vm9qp/UsQu0yrbYhnr68 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP -MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 -ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa -Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3 -YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw -qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv -Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6 -lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz -Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ -KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK -FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj -HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr -y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ -/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM -a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6 -fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG -SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi -7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc -SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza -ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc -XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg -iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho -L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF -Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr -kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+ -vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU -YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL -BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ -SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n -a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 -NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT -CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u -Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO -dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI -VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV -9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY -2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY -vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt -bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb -x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ -l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK -TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj -Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e -i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw -DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG -7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk -MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr -gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk -GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS -3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm -Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ -l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c -JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP -L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa -LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG -mpv0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw -CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg -R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 -MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT -ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw -EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW -+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 -ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI -zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW -tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 -/q4AaOeMSQ+2b1tbFfLn ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu -VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw -MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw -JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT -3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU -+ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp -S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 -bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi -T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL -vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK -Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK -dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT -c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv -l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N -iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD -ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH -6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt -LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 -nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 -+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK -W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT -AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq -l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG -4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ -mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A -7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu -VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN -MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 -MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 -ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy -RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS -bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF -/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R -3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw -EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy -9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V -GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ -2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV -WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD -W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN -AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj -t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV -DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 -TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G -lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW -mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df -WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 -+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ -tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA -GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv -8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 -MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 -ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD -VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j -b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq -scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO -xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H -LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX -uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD -yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ -JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q -rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN -BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L -hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB -QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ -HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu -Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg -QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB -BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx -MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA -A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb -laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 -awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo -JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw -LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT -VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk -LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb -UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ -QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ -naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls -QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD -VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 -ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G -CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y -OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx -FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp -Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP -kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc -cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U -fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 -N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC -xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 -+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM -Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG -SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h -mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk -ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c -2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t -HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD -VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw -MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV -UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy -b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR -ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb -hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 -FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV -L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB -iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl -MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw -NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG -EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N -aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ -Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 -ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 -HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm -gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ -jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc -aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG -YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 -W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K -UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH -+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q -W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC -LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC -gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 -tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh -SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 -TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 -pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR -xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp -GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 -dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN -AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB -RA+GsCyRxj3qrg+E ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM -BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG -T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx -CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD -b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA -iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH -38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE -HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz -kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP -szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq -vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf -nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG -YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo -0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a -CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K -AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I -36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB -Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN -qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj -cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm -+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL -hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe -lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 -p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 -piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR -LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX -5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO -dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul -9XXeifdy ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG -EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 -MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl -cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR -dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB -pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM -b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm -aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz -IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT -lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz -AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 -VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG -ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 -BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG -AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M -U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh -bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C -+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F -uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 -XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt -MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg -Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i -YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x -CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG -b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh -bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 -HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx -WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX -1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk -u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P -99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r -M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB -BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh -cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 -gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO -ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf -aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic -Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw -CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 -bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg -Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ -BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu -ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS -b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni -eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W -p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T -rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV -57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg -Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 -MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV -wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe -rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 -68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh -4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp -UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o -abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc -3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G -KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt -hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO -Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt -zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD -ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC -MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 -cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN -qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 -YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv -b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 -8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k -NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj -ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp -q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt -nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa -GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg -Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J -WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB -rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp -+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 -ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i -Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz -PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og -/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH -oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI -yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud -EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 -A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL -MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT -ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f -BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn -g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl -fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K -WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha -B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc -hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR -TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD -mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z -ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y -4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza -8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 -MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf -qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW -n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym -c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ -O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 -o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j -IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq -IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz -8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh -vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l -7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG -cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD -ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 -AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC -roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga -W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n -lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE -+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV -csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd -dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg -KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM -HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 -WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM -V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB -4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr -H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd -8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv -vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT -mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe -btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc -T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt -WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ -c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A -4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD -VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG -CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 -aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 -aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu -dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw -czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G -A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC -TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg -Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 -7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem -d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd -+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B -4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN -t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x -DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 -k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s -zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j -Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT -mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK -4SVhM7JZG+Ju1zdXtg2pEto= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 -MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR -/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu -FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR -U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c -ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR -FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k -A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw -eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl -sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp -VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q -A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ -ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD -ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px -KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI -FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv -oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg -u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP -0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf -3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl -8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ -DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN -PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ -ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx -NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv -bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA -VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku -WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX -5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ -ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg -h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV -BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE -CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy -MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G -A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD -DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq -M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf -OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa -4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 -HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR -aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA -b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ -Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV -PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO -pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu -UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY -MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV -HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 -9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW -s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 -Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg -cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM -79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz -/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt -ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm -Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK -QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ -w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi -S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 -mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz -WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 -b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS -b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI -7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg -CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud -EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD -VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T -kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ -gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE -BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK -DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz -OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv -bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R -xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX -qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC -C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 -6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh -/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF -YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E -JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc -US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 -ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm -+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi -M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G -A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV -cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc -Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs -PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ -q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 -cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr -a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I -H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y -K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu -nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf -oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY -Ic2wBlX7Jz9TkHCpBB5XJ7k= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw -CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT -U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2 -MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh -dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG -ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm -acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN -SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME -GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW -uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp -15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN -b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO -MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD -DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX -DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw -b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC -AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP -L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY -t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins -S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 -PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO -L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 -R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w -dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS -+YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS -d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG -AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f -gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j -BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z -NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt -hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM -QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf -R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ -DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW -P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy -lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq -bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w -AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q -r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji -Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU -98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL -BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 -ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw -NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L -cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg -Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN -QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT -3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw -3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 -3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 -BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN -XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF -AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw -8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG -nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP -oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy -d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg -LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw -CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T -ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN -MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG -A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT -ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC -WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ -6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B -Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa -qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q -4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf -MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD -Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw -HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY -MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp -YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa -ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz -SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf -iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X -ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 -IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS -VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE -SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu -+Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt -8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L -HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt -zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P -AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c -mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ -YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 -gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA -Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB -JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX -DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui -TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 -dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 -LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp -0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY -QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr -MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG -A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 -MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp -Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD -QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz -i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 -h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV -MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 -UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni -8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC -h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD -VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB -AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm -KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ -X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr -QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 -pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN -QSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz -MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv -cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz -Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO -0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao -wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj -7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS -8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT -BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg -JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 -6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ -3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm -D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS -CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx -MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg -Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ -iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa -/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ -jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI -HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 -sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w -gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw -KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG -AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L -URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO -H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm -I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY -iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT -AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD -VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx -NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT -HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5 -IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi -AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl -dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK -ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu -9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O -be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl -MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe -U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX -DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy -dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj -YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV -OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr -zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM -VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ -hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO -ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw -awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs -OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 -DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF -coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc -okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 -t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy -1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ -SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNV -BAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScw -JQYDVQQDEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2 -MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc -U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UEAxMeU2VjdXJpdHkg -Q29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4r -CmDvu20rhvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzA -lrenfna84xtSGc4RHwsENPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MG -TfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF7 -9+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGmnpjKIG58u4iFW/vAEGK7 -8vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtYXLVqAvO4 -g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3we -GVPKp7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst -+3A7caoreyYn8xrC3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M -0V9hvqG8OmpI6iZVIhZdXw3/JzOfGAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQ -T9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0VcwCBEF/VfR2ccCAwEAAaNCMEAw -HQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS -YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PA -FNr0Y/Dq9HHuTofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd -9XbXv8S2gVj/yP9kaWJ5rW4OH3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQI -UYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASxYfQAW0q3nHE3GYV5v4GwxxMOdnE+ -OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZXSEIx2C/pHF7uNke -gr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml+LLf -iAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUV -nuiZIesnKwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD -2NCcnWXL0CsnMQMeNuE9dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI// -1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm6Vwdp6POXiUyK+OVrCoHzrQoeIY8Laad -TdJ0MN1kURXbg4NR16/9M51NZg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY -MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t -dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 -WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD -VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 -9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ -DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 -Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N -QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ -xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G -A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG -kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr -Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 -Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU -JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot -RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl -MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp -U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw -NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE -ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp -ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 -DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf -8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN -+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 -X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa -K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA -1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G -A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR -zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 -YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD -bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 -L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D -eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp -VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY -WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs -ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw -MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj -aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp -Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg -nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 -HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N -Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN -dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 -HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G -CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU -sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 -4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg -8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 -mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs -ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD -VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy -ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy -dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p -OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 -8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K -Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe -hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk -6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q -AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI -bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB -ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z -qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn -0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN -sSi6 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln -biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF -MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT -d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 -76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ -bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c -6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE -emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd -MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt -MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y -MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y -FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi -aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM -gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB -qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 -lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn -8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov -L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 -45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO -UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 -O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC -bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv -GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a -77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC -hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 -92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp -Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w -ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt -Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE -BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu -IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow -RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY -U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv -Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br -YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF -nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH -6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt -eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ -c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ -MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH -HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf -jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 -5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB -rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU -F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c -wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 -cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB -AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp -WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 -xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ -2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ -IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 -aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X -em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR -dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ -OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ -hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy -tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd -AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC -FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi -1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq -jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ -wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ -WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy -NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC -uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw -IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 -g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN -9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP -BSeOE6Fuwg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN -8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ -RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 -hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 -ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM -EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 -A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy -WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ -1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 -6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT -91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p -TpPDpFQUWw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx -GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp -bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w -KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 -BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy -dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG -EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll -IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU -QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT -TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg -LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 -a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr -LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr -N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X -YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ -iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f -AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH -V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh -AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf -IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 -lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c -8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf -lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx -EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT -VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 -NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT -B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF -10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz -0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh -MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH -zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc -46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 -yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi -laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP -oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA -BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE -qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm -4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL -1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn -LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF -H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo -RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ -nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh -15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW -6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW -nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j -wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz -aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy -KwbQBM0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES -MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU -V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz -WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO -LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE -AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH -K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX -RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z -rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx -3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq -hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC -MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls -XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D -lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn -aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ -YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw -NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv -b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD -VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F -VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 -7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X -Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ -/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs -81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm -dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe -Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu -sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 -pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs -slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ -arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD -VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG -9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl -dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx -0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj -TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed -Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 -Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI -OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 -vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW -t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn -HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx -SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx -CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE -AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 -NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ -MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq -AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 -vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 -lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD -n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT -7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o -6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC -TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 -WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R -DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI -pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj -YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy -rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw -AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ -8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi -0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM -A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS -SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K -TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF -6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er -3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt -Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT -VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW -ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA -rBPuUBQemMc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM -BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp -ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe -Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw -IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU -cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS -T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK -AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1 -nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep -qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA -yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs -hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX -zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv -kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT -f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA -uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB -o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih -MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E -BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4 -wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2 -XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1 -JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j -ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV -VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx -xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on -AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d -7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj -gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV -+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo -FGWsJwt0ivKH ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw -WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs -IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y -MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD -VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz -dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx -s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw -LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij -YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD -pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE -AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR -UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj -/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw -CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x -ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 -c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx -OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI -SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI -b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB -ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn -swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu -7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 -1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW -80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP -JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l -RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw -hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 -coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc -BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n -twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud -DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W -0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe -uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q -lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB -aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE -sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT -MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe -qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh -VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 -h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 -EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK -yeC2nOnOcXHebD8WpHk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD -VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf -BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 -YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x -NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G -A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 -d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF -Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG -SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN -FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w -DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw -CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh -DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD -VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf -BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 -YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x -NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G -A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 -d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF -Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB -BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ -j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF -1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G -A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 -AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC -MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu -Sw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL -BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg -Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv -b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG -EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u -IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ -n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd -2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF -VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ -GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF -li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU -r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 -eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb -MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg -jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB -7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW -5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE -ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 -90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z -xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu -QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 -FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH -22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP -xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn -dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 -Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b -nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ -CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH -u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj -d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF -eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx -MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV -BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog -D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS -sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop -O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk -sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi -c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj -VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz -KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ -TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G -sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs -1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD -fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN -l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR -ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ -VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 -c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp -4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s -t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj -2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO -vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C -xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx -cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM -fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH -bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x -CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds -b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr -b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 -kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm -VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R -VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc -C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj -tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY -D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv -j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl -NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 -iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP -O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV -ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj -L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 -1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl -1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU -b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV -PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj -y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb -EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg -DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI -+Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy -YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX -UB+K+wb1whnw0A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl -eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT -JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT -Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg -VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo -I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng -o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G -A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB -zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW -RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB -iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl -cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV -BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw -MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV -BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B -3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY -tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ -Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 -VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT -79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 -c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT -Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l -c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee -UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE -Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF -Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO -VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 -ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs -8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR -iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze -Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ -XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ -qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB -VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB -L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG -jjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB -gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk -MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY -UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx -NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 -dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy -dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 -38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP -KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q -DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 -qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa -JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi -PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P -BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs -jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 -eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR -vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa -IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy -i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ -O+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT -AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD -QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP -MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do -0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ -UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d -RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ -OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv -JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C -AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O -BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ -LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY -MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ -44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I -Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw -i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN -9u6wWk5JRFRYX0KD ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV -BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g -Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ -BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ -R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF -dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw -vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ -uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp -n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs -cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW -xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P -rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF -DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx -DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy -LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C -eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ -d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq -kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC -b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl -qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 -OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c -NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk -ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO -pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj -03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk -PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE -1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX -QRBdJ3NghVdJIgc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV -BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk -LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv -b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ -BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg -THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v -IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv -xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H -Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB -eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo -jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ -+efcMQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe -MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 -ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw -IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL -SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH -SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh -ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X -DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 -TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ -fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA -sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU -WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS -nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH -dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip -NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC -AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF -MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB -uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl -PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP -JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ -gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 -j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 -5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB -o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS -/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z -Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE -W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D -hNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG -EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx -IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw -MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln -biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND -IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci -MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti -sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O -BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB -Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c -3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J -0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG -EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo -bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g -RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ -TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s -b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 -WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS -fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB -zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq -hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB -CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD -+JbNR6iC8hZVdyR+EhCVBCyj ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG -A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg -SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw -MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln -biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v -dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ -BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ -HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH -3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH -GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c -xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 -aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq -TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 -/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 -kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG -YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT -+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo -WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD -VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU -ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH -MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO -MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv -Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz -f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO -8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq -d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM -tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt -Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB -o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x -PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM -wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d -GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH -6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby -RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx -iN66zB+Afko= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw -RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY -BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz -MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u -LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0 -v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd -e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw -V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA -AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG -GJTO ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL -BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x -FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx -MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s -THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc -IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU -AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+ -GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9 -8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH -flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt -J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim -0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN -pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ -UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW -OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB -AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet -8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd -nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j -bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM -Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv -TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS -S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr -I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9 -b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB -UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P -Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven -sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s= ------END CERTIFICATE----- -`) diff --git a/server/ssl/ssl_test.go b/server/ssl/ssl_test.go index b425ec9a63..ef1925b50e 100644 --- a/server/ssl/ssl_test.go +++ b/server/ssl/ssl_test.go @@ -8,49 +8,25 @@ import ( "github.com/stretchr/testify/require" ) -func TestCertsFromFilePoolExists(t *testing.T) { - // Load hardcoded certificates found in ssl.go - certPool, certErr := createCertPoolFromEmbedded() - require.NoError(t, certErr) - - // Assert loaded certificates by looking at the length of the subjects array of strings - subjects := certPool.Subjects() - hardCodedSubNum := len(subjects) - assert.True(t, hardCodedSubNum > 0) - - // Load certificates from file - certificatesFile := "mockcertificates/mock-certs.pem" - certPool, err := AppendPEMFileToRootCAPool(certPool, certificatesFile) - - // Assert loaded certificates by looking at the length of the subjects array of strings - assert.NoError(t, err, "Error thrown by AppendPEMFileToRootCAPool while loading file %s: %v", certificatesFile, err) - subjects = certPool.Subjects() - subNumIncludingFile := len(subjects) - assert.True(t, subNumIncludingFile > hardCodedSubNum, "subNumIncludingFile should be greater than hardCodedSubNum") -} - -func TestCertsFromFilePoolDontExist(t *testing.T) { - // Empty certpool - var certPool *x509.CertPool = nil +func TestAppendPEMFileToCertPool(t *testing.T) { + t.Run("append-to-empty", func(t *testing.T) { + var certPool *x509.CertPool = nil - // Load certificates from file - certificatesFile := "mockcertificates/mock-certs.pem" - certPool, err := AppendPEMFileToRootCAPool(certPool, certificatesFile) + certificatesFile := "mockcertificates/mock-certs.pem" + certPool, err := AppendPEMFileToCertPool(certPool, certificatesFile) - // Assert loaded certificates by looking at the length of the subjects array of strings - assert.NoError(t, err, "Error thrown by AppendPEMFileToRootCAPool while loading file %s: %v", certificatesFile, err) - subjects := certPool.Subjects() - assert.Equal(t, len(subjects), 1, "We only loaded one certificate from the file, len(subjects) should equal 1") -} + require.NoError(t, err) + subjects := certPool.Subjects() + assert.Equal(t, len(subjects), 1) + }) -func TestAppendPEMFileToRootCAPoolFail(t *testing.T) { - // Empty certpool - var certPool *x509.CertPool + t.Run("fail", func(t *testing.T) { + var certPool *x509.CertPool - // In this test we are going to pass a file that does not exist as value of second argument - fakeCertificatesFile := "mockcertificates/NO-FILE.pem" - _, err := AppendPEMFileToRootCAPool(certPool, fakeCertificatesFile) + certificatesFile := "mockcertificates/NO-FILE.pem" + _, err := AppendPEMFileToCertPool(certPool, certificatesFile) - // Assert AppendPEMFileToRootCAPool correctly throws an error when trying to load an nonexisting file - assert.Errorf(t, err, "AppendPEMFileToRootCAPool should throw an error by while loading fake file %s \n", fakeCertificatesFile) + // expect an error from a file which doesn't exist + assert.Error(t, err) + }) } diff --git a/static/bidder-info/9dotsmedialtd.yaml b/static/bidder-info/9dotsmedialtd.yaml new file mode 100644 index 0000000000..ad9e7b3f07 --- /dev/null +++ b/static/bidder-info/9dotsmedialtd.yaml @@ -0,0 +1,2 @@ +endpoint: "http://ads-dot-pbs.ortb.net/openrtb/{{.PublisherID}}" +aliasOf: "limelightDigital" diff --git a/static/bidder-info/adagio.yaml b/static/bidder-info/adagio.yaml index 849665697b..8dbdf879e8 100644 --- a/static/bidder-info/adagio.yaml +++ b/static/bidder-info/adagio.yaml @@ -7,7 +7,7 @@ endpoint: "https://mp-REGION.4dex.io/pbserver" userSync: iframe: - url: "https://u-REGION.4dex.io/pbserver/usync.html?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&&gpp_sid={{.GPPSID}}&r={{.RedirectURL}}" + url: "https://u-REGION.4dex.io/pbserver/usync.html?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&r={{.RedirectURL}}" userMacro: "{UID}" disabled: true diff --git a/static/bidder-info/adastra.yaml b/static/bidder-info/adastra.yaml new file mode 100644 index 0000000000..2e06294181 --- /dev/null +++ b/static/bidder-info/adastra.yaml @@ -0,0 +1,5 @@ +endpoint: "https://adastra-prebid.attekmi.co/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +aliasOf: "smarthub" +userSync: + supports: + - redirect \ No newline at end of file diff --git a/static/bidder-info/addigi.yaml b/static/bidder-info/addigi.yaml index 8514d5c550..1952e5e7fd 100644 --- a/static/bidder-info/addigi.yaml +++ b/static/bidder-info/addigi.yaml @@ -1,2 +1,2 @@ -endpoint: "https://addigi-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +endpoint: "https://addigi-prebid.attekmi.co/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" aliasOf: "smarthub" diff --git a/static/bidder-info/adform.yaml b/static/bidder-info/adform.yaml index 6475bb34ca..b25507131b 100644 --- a/static/bidder-info/adform.yaml +++ b/static/bidder-info/adform.yaml @@ -1,4 +1,5 @@ aliasOf: adf +gvlVendorID: 50 userSync: redirect: url: "https://c1.adform.net/cookie?redirect_url={{.RedirectURL}}" diff --git a/static/bidder-info/adinify.yaml b/static/bidder-info/adinify.yaml index 501b54df3f..9f796ac970 100644 --- a/static/bidder-info/adinify.yaml +++ b/static/bidder-info/adinify.yaml @@ -1,2 +1,2 @@ -endpoint: "https://adinify-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +endpoint: "https://adinify-prebid.attekmi.co/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" aliasOf: "smarthub" diff --git a/static/bidder-info/adipolo.yaml b/static/bidder-info/adipolo.yaml index 0cf1ac3430..0189ca5ed3 100644 --- a/static/bidder-info/adipolo.yaml +++ b/static/bidder-info/adipolo.yaml @@ -2,10 +2,11 @@ aliasOf: xeworks endpoint: "http://rtb.adipolo.live?pid={{.SourceId}}&host={{.Host}}&pbs=1" maintainer: email: "smart@adipolo.com" +gvlVendorID: 1456 userSync: iframe: url: "https://sync.adipolo.live/static/adisync.html?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&cb={{.RedirectURL}}" userMacro: $UID redirect: url: "https://sync.adipolo.live/psync?t=s&e=0&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&cb={{.RedirectURL}}" - userMacro: "$UID" \ No newline at end of file + userMacro: "$UID" diff --git a/static/bidder-info/adklip.yaml b/static/bidder-info/adklip.yaml new file mode 100644 index 0000000000..89a7868fc3 --- /dev/null +++ b/static/bidder-info/adklip.yaml @@ -0,0 +1,8 @@ +aliasOf: aso +endpoint: "https://srv.adklip.net/pbs/bidder?zid={{.ZoneID}}" +maintainer: + email: "support@adklip.com" +userSync: + redirect: + url: "https://track.adklip.net/sync/v2?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&usp={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "{uid}" diff --git a/static/bidder-info/admaticde.yaml b/static/bidder-info/admaticde.yaml index 562aa18369..fdd9b6107d 100644 --- a/static/bidder-info/admaticde.yaml +++ b/static/bidder-info/admaticde.yaml @@ -1 +1,2 @@ -aliasOf: "admatic" \ No newline at end of file +aliasOf: "admatic" +gvlVendorID: 1281 \ No newline at end of file diff --git a/static/bidder-info/adnimation.yaml b/static/bidder-info/adnimation.yaml new file mode 100644 index 0000000000..308c048314 --- /dev/null +++ b/static/bidder-info/adnimation.yaml @@ -0,0 +1,8 @@ +aliasOf: "vidazoo" +endpoint: "https://exchange.adnimation.com/openrtb/" +maintainer: + email: "prebid@adnimation.com" +userSync: + iframe: + url: https://sync.adnimation.com/api/user/html/697a076271875e8907df35a6?pbs=true&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}} + userMacro: ${userId} diff --git a/static/bidder-info/adocean.yaml b/static/bidder-info/adocean.yaml deleted file mode 100644 index 3932a7a75e..0000000000 --- a/static/bidder-info/adocean.yaml +++ /dev/null @@ -1,16 +0,0 @@ -endpoint: "https://{{.Host}}.adocean.pl" -maintainer: - email: "aoteam@gemius.com" -gvlVendorID: 328 -capabilities: - app: - mediaTypes: - - banner - site: - mediaTypes: - - banner -userSync: - # adocean supports user syncing, but requires configuration by the host. contact this - # bidder directly at the email address in this file to ask about enabling user sync. - supports: - - redirect diff --git a/static/bidder-info/adoppler.yaml b/static/bidder-info/adoppler.yaml deleted file mode 100644 index 3db2c1f998..0000000000 --- a/static/bidder-info/adoppler.yaml +++ /dev/null @@ -1,12 +0,0 @@ -endpoint: "http://{{.AccountID}}.trustedmarketplace.io/ads/processHeaderBid/{{.AdUnit}}" -maintainer: - email: pbs@adoppler.com -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video diff --git a/static/bidder-info/adrubi.yaml b/static/bidder-info/adrubi.yaml new file mode 100644 index 0000000000..1d19dc7521 --- /dev/null +++ b/static/bidder-info/adrubi.yaml @@ -0,0 +1,4 @@ +aliasOf: "admatic" +maintainer: + email: "support@adrubi.com" +gvlVendorID: 779 \ No newline at end of file diff --git a/static/bidder-info/ads_interactive.yaml b/static/bidder-info/ads_interactive.yaml index dd857366b5..df45a6869e 100644 --- a/static/bidder-info/ads_interactive.yaml +++ b/static/bidder-info/ads_interactive.yaml @@ -1,18 +1,8 @@ +aliasOf: "teqblaze" endpoint: "https://bntb.adsinteractive.com/pserver" gvlVendorID: 1212 maintainer: email: "it@adsinteractive.com" -capabilities: - site: - mediaTypes: - - banner - - video - - native - app: - mediaTypes: - - banner - - video - - native userSync: redirect: url: "https://cstb.adsinteractive.com/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" diff --git a/static/bidder-info/adsinteractive.yaml b/static/bidder-info/adsinteractive.yaml index 095184725b..0940039929 100644 --- a/static/bidder-info/adsinteractive.yaml +++ b/static/bidder-info/adsinteractive.yaml @@ -1,17 +1,12 @@ -endpoint: "http://bid.adsinteractive.com/prebid" -maintainer: - email: it@adsinteractive.com +aliasOf: "teqblaze" +endpoint: "https://bntb.adsinteractive.com/pserver" gvlVendorID: 1212 -modifyingVastXmlAllowed: false -capabilities: - app: - mediaTypes: - - banner - site: - mediaTypes: - - banner +maintainer: + email: "it@adsinteractive.com" userSync: redirect: - url: "https://sync.adsinteractive.com/getuid?{{.RedirectURL}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}" - userMacro: "$AUID" - + url: "https://cstb.adsinteractive.com/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "[UID]" + iframe: + url: "https://cstb.adsinteractive.com/pbserverIframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&pbserverUrl={{.RedirectURL}}" + userMacro: "[UID]" \ No newline at end of file diff --git a/static/bidder-info/adsmovil.yaml b/static/bidder-info/adsmovil.yaml new file mode 100644 index 0000000000..2e919de4c6 --- /dev/null +++ b/static/bidder-info/adsmovil.yaml @@ -0,0 +1,16 @@ +aliasOf: "teqblaze" +endpoint: "https://tag-ssp.adsmovil.com/pserver" +maintainer: + email: "prebid@adsmovil.com" +capabilities: + site: + mediaTypes: + - banner + - video + - native + + app: + mediaTypes: + - banner + - video + - native \ No newline at end of file diff --git a/static/bidder-info/alchemyx.yaml b/static/bidder-info/alchemyx.yaml new file mode 100644 index 0000000000..2758dd6249 --- /dev/null +++ b/static/bidder-info/alchemyx.yaml @@ -0,0 +1,11 @@ +endpoint: "https://alchemyx.live/auction?id={{.AdUnit}}&auth={{.TokenID}}" +aliasOf: "adverxo" +maintainer: + email: "prebid@alchemyx.io" +userSync: + iframe: + url: https://alchemyx.online/usync?type=iframe&gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: $UID + redirect: + url: https://alchemyx.online/usync?type=image&gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: $UID diff --git a/static/bidder-info/alliance_gravity.yaml b/static/bidder-info/alliance_gravity.yaml new file mode 100644 index 0000000000..2557de1e83 --- /dev/null +++ b/static/bidder-info/alliance_gravity.yaml @@ -0,0 +1,24 @@ +endpoint: "https://pbs.production.agrvt.com/openrtb2/auction" +maintainer: + email: produit@alliancegravity.com +gvlVendorID: 501 +modifyingVastXmlAllowed: true +openrtb: + version: 2.6 +capabilities: + app: + mediaTypes: + - banner + - video + - audio + - native + site: + mediaTypes: + - banner + - video + - audio + - native +userSync: + iframe: + url: "https://pbs.production.agrvt.com/static/cookie_sync.html?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" + userMacro: "$UID" diff --git a/static/bidder-info/altstar.yaml b/static/bidder-info/altstar.yaml new file mode 100644 index 0000000000..1e8826ffb7 --- /dev/null +++ b/static/bidder-info/altstar.yaml @@ -0,0 +1,2 @@ +endpoint: "http://ads-pbs.ads-altstarmedia.com/openrtb/{{.PublisherID}}?host={{.Host}}" +aliasOf: "limelightDigital" \ No newline at end of file diff --git a/static/bidder-info/amcom.yaml b/static/bidder-info/amcom.yaml new file mode 100644 index 0000000000..2144fe6b2e --- /dev/null +++ b/static/bidder-info/amcom.yaml @@ -0,0 +1,2 @@ +endpoint: "https://amcom-prebid.attekmi.co/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +aliasOf: "smarthub" diff --git a/static/bidder-info/anzuDSP.yaml b/static/bidder-info/anzuDSP.yaml new file mode 100644 index 0000000000..c45d33e189 --- /dev/null +++ b/static/bidder-info/anzuDSP.yaml @@ -0,0 +1,9 @@ +aliasOf: "xeworks" +endpoint: "https://rtb.anzu-rtb.live/?pid={{.SourceId}}&host={{.Host}}&pbs=1" +maintainer: + email: "prebid@anzu.io" +userSync: + # anzuDSP supports user syncing, but requires configuration by the host. contact this + # bidder directly at the email address in this file to ask about enabling user sync. + supports: + - redirect diff --git a/static/bidder-info/anzuExchange.yaml b/static/bidder-info/anzuExchange.yaml new file mode 100644 index 0000000000..ae50ef3e7f --- /dev/null +++ b/static/bidder-info/anzuExchange.yaml @@ -0,0 +1,2 @@ +endpoint: "http://ads-pbs.marketplace-anzu.io/openrtb/{{.PublisherID}}?host={{.Host}}" +aliasOf: "limelightDigital" \ No newline at end of file diff --git a/static/bidder-info/anzuSSP.yaml b/static/bidder-info/anzuSSP.yaml new file mode 100644 index 0000000000..75aea96cab --- /dev/null +++ b/static/bidder-info/anzuSSP.yaml @@ -0,0 +1,16 @@ +aliasOf: "teqblaze" +endpoint: "http://endpoint.anzumarketplace.com/pserver" +maintainer: + email: "prebid@anzu.io" +capabilities: + site: + mediaTypes: + - banner + - video + - native + + app: + mediaTypes: + - banner + - video + - native \ No newline at end of file diff --git a/static/bidder-info/apester.yaml b/static/bidder-info/apester.yaml new file mode 100644 index 0000000000..c5bd2facd0 --- /dev/null +++ b/static/bidder-info/apester.yaml @@ -0,0 +1,9 @@ +aliasOf: "vidazoo" +endpoint: "https://bidder.apester.com/openrtb/" +maintainer: + email: "info@apester.com" +userSync: + iframe: + url: https://sync.apester.com/api/user/html/699dad2322a7fa644e1d8bf7?pbs=true&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}} + userMacro: ${userId} +gvlVendorID: 354 \ No newline at end of file diff --git a/static/bidder-info/appMonstaMedia.yaml b/static/bidder-info/appMonstaMedia.yaml new file mode 100644 index 0000000000..705140a525 --- /dev/null +++ b/static/bidder-info/appMonstaMedia.yaml @@ -0,0 +1,5 @@ +aliasOf: "teqblaze" +endpoint: "https://ssp-us.appmonsta.ai/pserver" +gvlVendorID: 1283 +maintainer: + email: "media.support@appmonsta.ai" diff --git a/static/bidder-info/artechnology.yaml b/static/bidder-info/artechnology.yaml index 0781235336..429ed3cda2 100644 --- a/static/bidder-info/artechnology.yaml +++ b/static/bidder-info/artechnology.yaml @@ -1,2 +1,2 @@ -endpoint: "https://artechnology-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +endpoint: "https://artechnology-prebid.attekmi.co/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" aliasOf: "smarthub" diff --git a/static/bidder-info/aso.yaml b/static/bidder-info/aso.yaml index 429b8441a5..6d0a86d490 100644 --- a/static/bidder-info/aso.yaml +++ b/static/bidder-info/aso.yaml @@ -14,8 +14,6 @@ capabilities: - video - native userSync: - # Adserver.Online supports user syncing, but requires configuration by the host.Contact this - # bidder directly at the email address in this file to ask about enabling user sync. - supports: - - redirect - - iframe + redirect: + url: "https://track.aso1.net/sync/v2?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&usp={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "{uid}" diff --git a/static/bidder-info/audienceNetwork.yaml b/static/bidder-info/audienceNetwork.yaml index e952def740..8b88d983c6 100644 --- a/static/bidder-info/audienceNetwork.yaml +++ b/static/bidder-info/audienceNetwork.yaml @@ -2,6 +2,8 @@ endpoint: "https://an.facebook.com/placementbid.ortb" disabled: true maintainer: email: "none" +openrtb: + multiformat-supported: true capabilities: app: mediaTypes: diff --git a/static/bidder-info/bcmint.yaml b/static/bidder-info/bcmint.yaml index 9d5a62cc51..8e42dcb986 100644 --- a/static/bidder-info/bcmint.yaml +++ b/static/bidder-info/bcmint.yaml @@ -3,8 +3,6 @@ endpoint: "https://srv.datacygnal.io/pbs/bidder?zid={{.ZoneID}}" maintainer: email: "contact@bcm.ltd" userSync: - # BCM Int. supports user syncing, but requires configuration by the host.Contact this - # bidder directly at the email address in this file to ask about enabling user sync. - supports: - - redirect - - iframe \ No newline at end of file + redirect: + url: "https://track.datacygnal.io/sync/v2?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&usp={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "{uid}" diff --git a/static/bidder-info/beop.yaml b/static/bidder-info/beop.yaml new file mode 100644 index 0000000000..1129818f85 --- /dev/null +++ b/static/bidder-info/beop.yaml @@ -0,0 +1,12 @@ +endpoint: "https://hb.collectiveaudience.co/rtb/bid" +endpointCompression: gzip +maintainer: + email: tech@collectiveaudience.co +gvlVendorID: 666 +openrtb: + version: 2.6 +capabilities: + site: + mediaTypes: + - banner + - video diff --git a/static/bidder-info/bidfuse.yaml b/static/bidder-info/bidfuse.yaml new file mode 100644 index 0000000000..c993e2f184 --- /dev/null +++ b/static/bidder-info/bidfuse.yaml @@ -0,0 +1,11 @@ +aliasOf: "teqblaze" +endpoint: "https://bn.bidfuse.com/pserver" +maintainer: + email: "support@bidfuse.com" +userSync: + redirect: + url: "https://syncbf.bidfuse.com/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "[UID]" + iframe: + url: "https://syncbf.bidfuse.com/pbserverIframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&pbserverUrl={{.RedirectURL}}" + userMacro: "[UID]" \ No newline at end of file diff --git a/static/bidder-info/bidgency.yaml b/static/bidder-info/bidgency.yaml index ad5816dffe..e4885897d1 100644 --- a/static/bidder-info/bidgency.yaml +++ b/static/bidder-info/bidgency.yaml @@ -3,8 +3,6 @@ endpoint: "https://srv.bidgx.com/pbs/bidder?zid={{.ZoneID}}" maintainer: email: "aso@bidgency.com" userSync: - # Bidgency supports user syncing, but requires configuration by the host.Contact this - # bidder directly at the email address in this file to ask about enabling user sync. - supports: - - redirect - - iframe \ No newline at end of file + redirect: + url: "https://track.bidgx.com/sync/v2?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&usp={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "{uid}" diff --git a/static/bidder-info/copper6.yaml b/static/bidder-info/copper6.yaml index b4e259ef08..fe3ea47a29 100644 --- a/static/bidder-info/copper6.yaml +++ b/static/bidder-info/copper6.yaml @@ -2,6 +2,7 @@ aliasOf: adtelligent endpoint: "http://ghb.app.copper6.com/pbs/ortb" maintainer: email: "info@copper6.com" +gvlVendorID: 1356 userSync: # Copper6 ssp supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. diff --git a/static/bidder-info/cortex.yaml b/static/bidder-info/cortex.yaml new file mode 100644 index 0000000000..e7b5868ea6 --- /dev/null +++ b/static/bidder-info/cortex.yaml @@ -0,0 +1,24 @@ +aliasOf: "teqblaze" +# We have the following regional endpoint domains: 'eu' - for EU, 'us-east' - for US_EAST, 'apac' - for APAC +# Please deploy this config in each of your datacenters with the appropriate regional subdomain +endpoint: "https://REGION.targetadserver.com/pserver" +maintainer: + email: "dev@cortextech.it" +capabilities: + site: + mediaTypes: + - banner + - video + - native + app: + mediaTypes: + - banner + - video + - native +userSync: + redirect: + url: "https://sync.targetadserver.com/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "[UID]" + iframe: + url: "https://sync.targetadserver.com/pbserverIframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&pbserverUrl={{.RedirectURL}}" + userMacro: "[UID]" diff --git a/static/bidder-info/cwire.yaml b/static/bidder-info/cwire.yaml index b7a16e05c3..eabe2b61b8 100644 --- a/static/bidder-info/cwire.yaml +++ b/static/bidder-info/cwire.yaml @@ -3,14 +3,16 @@ maintainer: email: "devs@cwire.com" endpointCompression: gzip gvlVendorID: 1081 -modifyingVastXmlAllowed: false +modifyingVastXmlAllowed: true capabilities: app: mediaTypes: - banner + - video site: mediaTypes: - banner + - video userSync: iframe: url: https://prebid.cwi.re/v1/usersync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&rd={{.RedirectURL}} diff --git a/static/bidder-info/deepintent.yaml b/static/bidder-info/deepintent.yaml index 95aba4207a..c19b29f90d 100644 --- a/static/bidder-info/deepintent.yaml +++ b/static/bidder-info/deepintent.yaml @@ -1,4 +1,6 @@ endpoint: "https://prebid.deepintent.com/prebid" +geoscope: + - USA maintainer: email: "prebiddev@deepintent.com" gvlVendorID: 541 diff --git a/static/bidder-info/displayio.yaml b/static/bidder-info/displayio.yaml index 4b3b28b745..6c2a04b65f 100644 --- a/static/bidder-info/displayio.yaml +++ b/static/bidder-info/displayio.yaml @@ -10,7 +10,11 @@ capabilities: mediaTypes: - banner - video + - audio + - native site: mediaTypes: - banner - - video \ No newline at end of file + - video + - audio + - native \ No newline at end of file diff --git a/static/bidder-info/dpai.yaml b/static/bidder-info/dpai.yaml new file mode 100644 index 0000000000..f679d66d77 --- /dev/null +++ b/static/bidder-info/dpai.yaml @@ -0,0 +1,22 @@ +aliasOf: "teqblaze" +endpoint: "https://ssp.drift-pixel.ai/pserver" +maintainer: + email: "adops@driftpixel.ai" +capabilities: + site: + mediaTypes: + - banner + - video + - native + app: + mediaTypes: + - banner + - video + - native +userSync: + redirect: + url: "https://sync.drift-pixel.ai/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "[UID]" + iframe: + url: "https://sync.drift-pixel.ai/pbserverIframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&pbserverUrl={{.RedirectURL}}" + userMacro: "[UID]" diff --git a/static/bidder-info/dxkulture.yaml b/static/bidder-info/dxkulture.yaml deleted file mode 100644 index d6f03044fd..0000000000 --- a/static/bidder-info/dxkulture.yaml +++ /dev/null @@ -1,16 +0,0 @@ -endpoint: "https://ads.dxkulture.com/pbs" -maintainer: - email: "devops@dxkulture.com" -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video -userSync: - redirect: - url: "https://ads.dxkulture.com/usync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&cb={{.RedirectURL}}" - userMacro: "$UID" diff --git a/static/bidder-info/elementaltv.yaml b/static/bidder-info/elementaltv.yaml new file mode 100644 index 0000000000..ffc219f7f7 --- /dev/null +++ b/static/bidder-info/elementaltv.yaml @@ -0,0 +1,17 @@ +endpoint: "https://pbs.elementaltv.io/ads/processHeaderBid/{{.AdUnit}}" +endpointCompression: gzip +openrtb: + version: 2.6 +maintainer: + email: support@elementaltv.com +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native diff --git a/static/bidder-info/epsilon.yaml b/static/bidder-info/epsilon.yaml index cb8318102e..4da155b06f 100644 --- a/static/bidder-info/epsilon.yaml +++ b/static/bidder-info/epsilon.yaml @@ -1,4 +1,5 @@ aliasOf: conversant +gvlVendorID: 24 userSync: redirect: url: "https://prebid-match.dotomi.com/match/bounce/current?version=1&networkId=72582&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&rurl={{.RedirectURL}}" diff --git a/static/bidder-info/equativ.yaml b/static/bidder-info/equativ.yaml index 7c5214fe48..512da14d50 100644 --- a/static/bidder-info/equativ.yaml +++ b/static/bidder-info/equativ.yaml @@ -1 +1,2 @@ aliasOf: "smartadserver" +gvlVendorID: 45 diff --git a/static/bidder-info/eskimi.yaml b/static/bidder-info/eskimi.yaml new file mode 100644 index 0000000000..c3e02c49eb --- /dev/null +++ b/static/bidder-info/eskimi.yaml @@ -0,0 +1,21 @@ +endpoint: "https://ittr.eskimi.com/prebidjs" +maintainer: + email: prebid@eskimi.com +gvlVendorID: 814 +modifyingVastXmlAllowed: false +openrtb: + version: 2.6 + gpp-supported: true +capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video +userSync: + redirect: + url: "https://ittpx.eskimi.com/sync?sp_id=137&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&dest={{.RedirectURL}}" + userMacro: "${USER_ID}" diff --git a/static/bidder-info/ezoic.yaml b/static/bidder-info/ezoic.yaml new file mode 100644 index 0000000000..9f8be82b52 --- /dev/null +++ b/static/bidder-info/ezoic.yaml @@ -0,0 +1,23 @@ +# Ezoic requires publisher domains to be registered and approved before +# bidding; unapproved inventory receives no-bid responses. Contact +# prebid@ezoic.com to get set up. +endpoint: "https://g.ezoic.net/ezoic/prebid/adapter/ortb" +maintainer: + email: prebid@ezoic.com +gvlVendorID: 347 +geoscope: + - global +openrtb: + version: 2.6 +modifyingVastXmlAllowed: false +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native diff --git a/static/bidder-info/felixads.yaml b/static/bidder-info/felixads.yaml index baa2268f4d..2068293eaa 100644 --- a/static/bidder-info/felixads.yaml +++ b/static/bidder-info/felixads.yaml @@ -1,2 +1,2 @@ -endpoint: "https://felixads-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +endpoint: "https://felixads-prebid.attekmi.co/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" aliasOf: "smarthub" diff --git a/static/bidder-info/finative.yaml b/static/bidder-info/finative.yaml index e1136c3220..9201f4eb3f 100644 --- a/static/bidder-info/finative.yaml +++ b/static/bidder-info/finative.yaml @@ -1,2 +1,3 @@ endpoint: "https://b.finative.cloud/cds/rtb/bid?ssp={{.AccountID}}" -aliasOf: "seedingAlliance" \ No newline at end of file +aliasOf: "seedingAlliance" +gvlVendorID: 371 \ No newline at end of file diff --git a/static/bidder-info/flipp.yaml b/static/bidder-info/flipp.yaml index 431c134579..01772ab41e 100644 --- a/static/bidder-info/flipp.yaml +++ b/static/bidder-info/flipp.yaml @@ -1,4 +1,4 @@ -endpoint: "https://cdn-gateflipp.flippback.com/flyer-locator-service/prebid_campaigns" +endpoint: "https://ads-flipp.com/flyer-locator-service/prebid_campaigns" maintainer: email: prebid@flipp.com capabilities: diff --git a/static/bidder-info/freewheel-ssp.yaml b/static/bidder-info/freewheel-ssp.yaml index 43c1ca166a..4b79dd12ab 100644 --- a/static/bidder-info/freewheel-ssp.yaml +++ b/static/bidder-info/freewheel-ssp.yaml @@ -1,4 +1,5 @@ aliasOf: freewheelssp +gvlVendorID: 285 userSync: iframe: url: "https://ads.stickyadstv.com/pbs-user-sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&r={{.RedirectURL}}" diff --git a/static/bidder-info/gothamads.yaml b/static/bidder-info/gothamads.yaml deleted file mode 100644 index c9f4e66b48..0000000000 --- a/static/bidder-info/gothamads.yaml +++ /dev/null @@ -1,14 +0,0 @@ -endpoint: "http://us-e-node1.gothamads.com/?pass={{.AccountID}}" -maintainer: - email: "support@gothamads.com" -capabilities: - app: - mediaTypes: - - banner - - video - - native - site: - mediaTypes: - - banner - - video - - native \ No newline at end of file diff --git a/static/bidder-info/harion.yaml b/static/bidder-info/harion.yaml new file mode 100644 index 0000000000..450afd8644 --- /dev/null +++ b/static/bidder-info/harion.yaml @@ -0,0 +1,17 @@ +aliasOf: "teqblaze" +endpoint: "https://usads.harion-ma.com/pserver" +maintainer: + email: "adtech@markappmedia.site" +gvlVendorID: 1406 +capabilities: + site: + mediaTypes: + - banner + - video + - native + + app: + mediaTypes: + - banner + - video + - native diff --git a/static/bidder-info/harrenmedia.yaml b/static/bidder-info/harrenmedia.yaml new file mode 100644 index 0000000000..aaafa8d446 --- /dev/null +++ b/static/bidder-info/harrenmedia.yaml @@ -0,0 +1,9 @@ +endpoint: "https://harrenmedia.pbsadverxo.com/auction?id={{.AdUnit}}&auth={{.TokenID}}" +aliasOf: "adverxo" +userSync: + iframe: + url: https://hmidssp.com/usync?type=iframe&gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: $UID + redirect: + url: https://hmidssp.com/usync?type=image&gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: $UID diff --git a/static/bidder-info/imds.yaml b/static/bidder-info/imds.yaml index 135b67fc1f..73f2099548 100644 --- a/static/bidder-info/imds.yaml +++ b/static/bidder-info/imds.yaml @@ -15,7 +15,6 @@ capabilities: - banner - video userSync: - supportCors: true iframe: url: "https://ad-cdn.technoratimedia.com/html/usersync.html?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gppsid={{.GPPSID}}&cb={{.RedirectURL}}" userMacro: "[USER_ID]" diff --git a/static/bidder-info/indicue.yaml b/static/bidder-info/indicue.yaml index 1353424dfe..b6b2bccc80 100644 --- a/static/bidder-info/indicue.yaml +++ b/static/bidder-info/indicue.yaml @@ -2,6 +2,7 @@ aliasOf: adtelligent endpoint: "http://ghb.console.indicue.com/pbs/ortb" maintainer: email: "ops@indicue.com" +gvlVendorID: 0 userSync: # Indicue ssp supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. diff --git a/static/bidder-info/insticator.yaml b/static/bidder-info/insticator.yaml index 907ff4a50d..adef8536d6 100644 --- a/static/bidder-info/insticator.yaml +++ b/static/bidder-info/insticator.yaml @@ -1,7 +1,11 @@ endpoint: "https://ex.ingage.tech/v1/prebidserver" +extra_info: '{"app_endpoint":"https://aex.ingage.tech/v1/prebidserver"}' +endpointCompression: GZIP maintainer: email: "prebid@insticator.com" gvlVendorID: 910 +openrtb: + version: "2.6" capabilities: app: mediaTypes: diff --git a/static/bidder-info/intenze.yaml b/static/bidder-info/intenze.yaml index 14eec4d694..fe8d7635ad 100644 --- a/static/bidder-info/intenze.yaml +++ b/static/bidder-info/intenze.yaml @@ -1,4 +1,14 @@ -aliasOf: "gothamads" endpoint: "http://lb-east.intenze.co/?pass={{.AccountID}}" maintainer: - email: "connect@intenze.co" \ No newline at end of file + email: "connect@intenze.co" +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native diff --git a/static/bidder-info/intertech.yaml b/static/bidder-info/intertech.yaml deleted file mode 100644 index bf4b52bc38..0000000000 --- a/static/bidder-info/intertech.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# This adapter is ported from PBS-Java to PBS-Go by Prebid. Please open a GitHub issue instead of -# directly contacting the maintainer for technical issues. -endpoint: https://prebid.intertechsrvcs.com/prebid/{{.PageID}}?imp-id={{.ImpID}}&ssp-id=10500 -endpointCompression: GZIP -maintainer: - email: prebid@intertechsrvcs.com -capabilities: - site: - mediaTypes: - - banner - - native -userSync: - redirect: - url: https://prebid.intertechsrvcs.com/mapuid/intertech/?ssp-id=10500&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&location= - userMacro: "{UID}" \ No newline at end of file diff --git a/static/bidder-info/jambojar.yaml b/static/bidder-info/jambojar.yaml index 5ab15a47d4..794e804e17 100644 --- a/static/bidder-info/jambojar.yaml +++ b/static/bidder-info/jambojar.yaml @@ -1,2 +1,2 @@ -endpoint: "https://jambojar-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +endpoint: "https://jambojar-prebid.attekmi.co/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" aliasOf: "smarthub" diff --git a/static/bidder-info/janet.yaml b/static/bidder-info/janet.yaml index 97f44a2bd5..4a77ef6f48 100644 --- a/static/bidder-info/janet.yaml +++ b/static/bidder-info/janet.yaml @@ -2,6 +2,7 @@ aliasOf: adtelligent endpoint: "http://ghb.bidder.jmgads.com/pbs/ortb" maintainer: email: "info@thejmg.com" +gvlVendorID: 410 userSync: # JANet supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. diff --git a/static/bidder-info/jdpmedia.yaml b/static/bidder-info/jdpmedia.yaml index f558955a2f..2315db74ba 100644 --- a/static/bidder-info/jdpmedia.yaml +++ b/static/bidder-info/jdpmedia.yaml @@ -1,4 +1,4 @@ -endpoint: "https://jdpmedia-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +endpoint: "https://jdpmedia-prebid.attekmi.co/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" aliasOf: "smarthub" userSync: supports: diff --git a/static/bidder-info/kargo.yaml b/static/bidder-info/kargo.yaml index 6acd679ebc..1347a87eb4 100644 --- a/static/bidder-info/kargo.yaml +++ b/static/bidder-info/kargo.yaml @@ -1,4 +1,4 @@ -endpoint: "https://krk.kargo.com/api/v1/openrtb" +endpoint: "https://krk2.kargo.com/api/v1/openrtb" maintainer: email: "kraken@kargo.com" gvlVendorID: 972 @@ -9,6 +9,11 @@ capabilities: - banner - video - native + app: + mediaTypes: + - banner + - video + - native userSync: redirect: url: "https://crb.kargo.com/api/v1/dsync/PrebidServer?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&r={{.RedirectURL}}" diff --git a/static/bidder-info/kuantyx.yaml b/static/bidder-info/kuantyx.yaml index b4a2402450..6b92e8c4e7 100644 --- a/static/bidder-info/kuantyx.yaml +++ b/static/bidder-info/kuantyx.yaml @@ -3,8 +3,6 @@ endpoint: "https://srv.kntxy.com/pbs/bidder?zid={{.ZoneID}}" maintainer: email: "ssp@kuantyx.com" userSync: - # Kuantyx supports user syncing, but requires configuration by the host.Contact this - # bidder directly at the email address in this file to ask about enabling user sync. - supports: - - redirect - - iframe + redirect: + url: "https://track.kntxy.com/sync/v2?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&usp={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "{uid}" diff --git a/static/bidder-info/m152.yaml b/static/bidder-info/m152.yaml new file mode 100644 index 0000000000..4bc67f075e --- /dev/null +++ b/static/bidder-info/m152.yaml @@ -0,0 +1,15 @@ +disabled: true +# We have the following regional endpoint domains: 'east' - for US_EAST, 'eu' - for EU +# Please deploy this config in each of your datacenters with the appropriate regional subdomain +aliasOf: "teqblaze" +endpoint: "https://#{REGION}#.152media-ssp.com/pserver" +maintainer: + email: "info@152media.com" +gvlVendorID: 1111 +userSync: + redirect: + url: "https://cs.152media-ssp.com/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "[UID]" + iframe: + url: "https://cs.152media-ssp.com/pbserverIframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&pbserverUrl={{.RedirectURL}}" + userMacro: "[UID]" diff --git a/static/bidder-info/magnite.yaml b/static/bidder-info/magnite.yaml index 109c20d03b..a0840a14a8 100644 --- a/static/bidder-info/magnite.yaml +++ b/static/bidder-info/magnite.yaml @@ -1 +1,2 @@ -aliasOf: "rubicon" \ No newline at end of file +aliasOf: "rubicon" +gvlVendorID: 52 \ No newline at end of file diff --git a/static/bidder-info/markapp.yaml b/static/bidder-info/markapp.yaml index b0e7106242..a55108cbe0 100644 --- a/static/bidder-info/markapp.yaml +++ b/static/bidder-info/markapp.yaml @@ -1,4 +1,4 @@ -endpoint: "https://markapp-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +endpoint: "https://markapp-prebid.attekmi.co/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" aliasOf: "smarthub" userSync: supports: diff --git a/static/bidder-info/matterfull.yaml b/static/bidder-info/matterfull.yaml new file mode 100644 index 0000000000..80a007a85c --- /dev/null +++ b/static/bidder-info/matterfull.yaml @@ -0,0 +1,9 @@ +aliasOf: "xeworks" +endpoint: "https://rtb.mtflll.com?pid={{.SourceId}}&host={{.Host}}&pbs=1" +maintainer: + email: "adops@bematterfull.com" +userSync: + # matterfull supports user syncing, but requires configuration by the host. contact this + # bidder directly at the email address in this file to ask about enabling user sync. + supports: + - redirect diff --git a/static/bidder-info/medianet.yaml b/static/bidder-info/medianet.yaml index effd768206..73c1830e3e 100644 --- a/static/bidder-info/medianet.yaml +++ b/static/bidder-info/medianet.yaml @@ -23,5 +23,5 @@ userSync: url: https://hbx.media.net/checksync.php?cid=8CUEHS6F9&cs=87&type=mpbc&cv=37&vsSync=1&uspstring={{.USPrivacy}}&gdpr={{.GDPR}}&gdprstring={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redirect={{.RedirectURL}} userMacro: "" redirect: - url: https://hbx.media.net/cksync.php?cs=1&type=pbs&ovsid=setstatuscode&bidder=medianet&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}} - userMacro: "" \ No newline at end of file + url: https://cs.media.net/cksync.php?cs=1&type=pbs&ovsid=setstatuscode&bidder=medianet&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}} + userMacro: "" diff --git a/static/bidder-info/mediasquare.yaml b/static/bidder-info/mediasquare.yaml index b6d21f4c9f..8a5730c509 100644 --- a/static/bidder-info/mediasquare.yaml +++ b/static/bidder-info/mediasquare.yaml @@ -10,3 +10,12 @@ capabilities: - banner - video - native + site: + mediaTypes: + - banner + - video + - native +userSync: + redirect: + url: https://pbs-front.mediasquare.fr/sync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: $UID diff --git a/static/bidder-info/mgtechnology.yaml b/static/bidder-info/mgtechnology.yaml new file mode 100644 index 0000000000..24e8544a74 --- /dev/null +++ b/static/bidder-info/mgtechnology.yaml @@ -0,0 +1,25 @@ +# MediaGo Technology LLC - alias of mediago with separate endpoint, GVL ID, and user sync +aliasOf: mediago +endpoint: "https://gbid.mediagotechnology.com/api/bid?tn={{.AccountID}}" +endpointCompression: gzip +geoscope: + - USA + - DEU + - JPN + - GBR + - KOR + - CAN + - FRA + - ITA +maintainer: + email: ext_mediago_cm@baidu.com +gvlVendorID: 1575 +capabilities: + site: + mediaTypes: + - banner + - native +userSync: + redirect: + url: https://go.mediagotechnology.com/ju/cs/prebid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: $UID diff --git a/static/bidder-info/mobilefuse.yaml b/static/bidder-info/mobilefuse.yaml index 14e488d077..c0770d80c2 100644 --- a/static/bidder-info/mobilefuse.yaml +++ b/static/bidder-info/mobilefuse.yaml @@ -12,6 +12,11 @@ capabilities: - banner - video - native + site: + mediaTypes: + - banner + - video + - native endpointCompression: "GZIP" openrtb: version: 2.6 diff --git a/static/bidder-info/mobupps.yaml b/static/bidder-info/mobupps.yaml deleted file mode 100644 index bb35990b80..0000000000 --- a/static/bidder-info/mobupps.yaml +++ /dev/null @@ -1,9 +0,0 @@ -endpoint: "https://mobupps.pbsadverxo.com/auction?id={{.AdUnit}}&auth={{.TokenID}}" -aliasOf: "adverxo" -userSync: - iframe: - url: https://mobupps.pbsadverxo.com/usync?type=iframe&gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} - userMacro: $UID - redirect: - url: https://mobupps.pbsadverxo.com/usync?type=image&gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} - userMacro: $UID diff --git a/static/bidder-info/monetixads.yaml b/static/bidder-info/monetixads.yaml index 95beda701f..32b0d79280 100644 --- a/static/bidder-info/monetixads.yaml +++ b/static/bidder-info/monetixads.yaml @@ -1,3 +1,4 @@ aliasOf: "admatic" maintainer: - email: "team@monetixads.com" \ No newline at end of file + email: "team@monetixads.com" +gvlVendorID: 1281 \ No newline at end of file diff --git a/static/bidder-info/mycodemedia.yaml b/static/bidder-info/mycodemedia.yaml new file mode 100644 index 0000000000..88b0547773 --- /dev/null +++ b/static/bidder-info/mycodemedia.yaml @@ -0,0 +1,22 @@ +aliasOf: "teqblaze" +endpoint: 'https://east-backend.mycodemedia.com/pserver' +maintainer: + email: 'support-platform@mycodemedia.com' +capabilities: + site: + mediaTypes: + - banner + - video + - native + app: + mediaTypes: + - banner + - video + - native +userSync: + redirect: + url: "https://usersync.mycodemedia.com/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "[UID]" + iframe: + url: "https://usersync.mycodemedia.com/pbserverIframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&pbserverUrl={{.RedirectURL}}" + userMacro: "[UID]" diff --git a/static/bidder-info/netaddiction.yaml b/static/bidder-info/netaddiction.yaml index 7f6777b4b3..70a26fca5f 100644 --- a/static/bidder-info/netaddiction.yaml +++ b/static/bidder-info/netaddiction.yaml @@ -1,3 +1,4 @@ aliasOf: "admatic" maintainer: - email: "publishers-support@netaddiction.it" \ No newline at end of file + email: "publishers-support@netaddiction.it" +gvlVendorID: 1281 \ No newline at end of file diff --git a/static/bidder-info/nexx360.yaml b/static/bidder-info/nexx360.yaml index 0a0b186ec9..c96b088fec 100644 --- a/static/bidder-info/nexx360.yaml +++ b/static/bidder-info/nexx360.yaml @@ -1,6 +1,7 @@ endpoint: "http://fast.nexx360.io/prebid-server" maintainer: email: "tech@nexx360.io" +gvlVendorID: 965 endpointCompression: gzip geoscope: - global @@ -17,3 +18,10 @@ capabilities: - video - native - audio +userSync: + redirect: + url: "https://fast.nexx360.io/usermatchredir/redirect?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gppsid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "$UID" + iframe: + url: "https://fast.nexx360.io/usermatchredir/iframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gppsid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "$UID" diff --git a/static/bidder-info/ntvagents.yaml b/static/bidder-info/ntvagents.yaml new file mode 100644 index 0000000000..1b34a11c13 --- /dev/null +++ b/static/bidder-info/ntvagents.yaml @@ -0,0 +1,11 @@ +aliasOf: "teqblaze" +endpoint: "https://endpoint1.nativeagents.ai/pserver" +maintainer: + email: "prebid@nativeagents.ai" +userSync: + redirect: + url: "https://sync.nativeagents.ai/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "[UID]" + iframe: + url: "https://sync.nativeagents.ai/pbserverIframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&pbserverUrl={{.RedirectURL}}" + userMacro: "[UID]" diff --git a/static/bidder-info/nuba.yaml b/static/bidder-info/nuba.yaml new file mode 100644 index 0000000000..803402c68a --- /dev/null +++ b/static/bidder-info/nuba.yaml @@ -0,0 +1,4 @@ +aliasOf: "teqblaze" +endpoint: "https://ads.nuba.io/pserver" +maintainer: + email: "tech@nuba.io" diff --git a/static/bidder-info/nuclion.yaml b/static/bidder-info/nuclion.yaml new file mode 100644 index 0000000000..070512409b --- /dev/null +++ b/static/bidder-info/nuclion.yaml @@ -0,0 +1,2 @@ +endpoint: "http://ads-pbs.rtb-nuclion.io/openrtb/{{.PublisherID}}?host={{.Host}}" +aliasOf: "limelightDigital" diff --git a/static/bidder-info/optidigital.yaml b/static/bidder-info/optidigital.yaml index b0df8a5ef8..30074e3a6f 100644 --- a/static/bidder-info/optidigital.yaml +++ b/static/bidder-info/optidigital.yaml @@ -19,5 +19,5 @@ userSync: supports: - iframe iframe: - url: "https://scripts.opti-digital.com/js/presyncs2s.html?endpoint=optidigital&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" + url: "https://scripts.opti-digital.com/js/presyncs2s.html?endpoint=optidigital&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" userMacro: "$UID" \ No newline at end of file diff --git a/static/bidder-info/orbidder.yaml b/static/bidder-info/orbidder.yaml index c42fb91de4..74348c75d7 100644 --- a/static/bidder-info/orbidder.yaml +++ b/static/bidder-info/orbidder.yaml @@ -11,7 +11,6 @@ capabilities: - banner - native userSync: - supportCors: true redirect: url: "https://orbidder.otto.de/pbs-usersync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&redirect={{.RedirectURL}}" userMacro: "[ODN_ID]" \ No newline at end of file diff --git a/static/bidder-info/oveeo.yaml b/static/bidder-info/oveeo.yaml new file mode 100644 index 0000000000..388fea5ed6 --- /dev/null +++ b/static/bidder-info/oveeo.yaml @@ -0,0 +1,2 @@ +endpoint: "http://ads-pbs.rtb-oveeo.com/openrtb/{{.PublisherID}}?host={{.Host}}" +aliasOf: "limelightDigital" \ No newline at end of file diff --git a/static/bidder-info/pgam.yaml b/static/bidder-info/pgam.yaml index e0bf4388d4..911fa4ef08 100644 --- a/static/bidder-info/pgam.yaml +++ b/static/bidder-info/pgam.yaml @@ -2,6 +2,7 @@ aliasOf: adtelligent endpoint: "http://ghb.pgamssp.com/pbs/ortb" maintainer: email: "ppatel@pgammedia.com" +gvlVendorID: 1353 userSync: # PGAM ssp supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. diff --git a/static/bidder-info/pgamrtb.yaml b/static/bidder-info/pgamrtb.yaml new file mode 100644 index 0000000000..718c341d54 --- /dev/null +++ b/static/bidder-info/pgamrtb.yaml @@ -0,0 +1,2 @@ +endpoint: "http://ads-pbs.pgamrtb.com/openrtb/{{.PublisherID}}?host={{.Host}}" +aliasOf: "limelightDigital" diff --git a/static/bidder-info/pixad.yaml b/static/bidder-info/pixad.yaml index d08230bfbc..bc9a6fe699 100644 --- a/static/bidder-info/pixad.yaml +++ b/static/bidder-info/pixad.yaml @@ -1,3 +1,4 @@ aliasOf: "admatic" maintainer: - email: "prebid@pixad.com.tr" \ No newline at end of file + email: "prebid@pixad.com.tr" +gvlVendorID: 1281 \ No newline at end of file diff --git a/static/bidder-info/pixfuture.yaml b/static/bidder-info/pixfuture.yaml new file mode 100644 index 0000000000..1f1e78b6b8 --- /dev/null +++ b/static/bidder-info/pixfuture.yaml @@ -0,0 +1,19 @@ +endpoint: "https://pbs-pix.pixfuture.com/pixservices" +maintainer: + email: "client-support@pixfuture.com" +gvlVendorID: 839 +capabilities: + site: + mediaTypes: + - banner + - video + - native + app: + mediaTypes: + - banner + - video + - native +userSync: + redirect: + url: "https://sync.pixfuture.com/cookiesync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}" + userMacro: "${UID}" diff --git a/static/bidder-info/programmaticX.yaml b/static/bidder-info/programmaticX.yaml new file mode 100644 index 0000000000..0e203e8e46 --- /dev/null +++ b/static/bidder-info/programmaticX.yaml @@ -0,0 +1,9 @@ +aliasOf: "vidazoo" +endpoint: "https://exchange.programmaticx.ai/openrtb/" +maintainer: + email: "pxteam@programmaticx.ai" +gvlVendorID: 1344 +userSync: + iframe: + url: https://sync.programmaticx.ai/api/user/html/685297194d85991a5e6e36dd?pbs=true&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}} + userMacro: ${userId} \ No newline at end of file diff --git a/static/bidder-info/progx.yaml b/static/bidder-info/progx.yaml index 0e203e8e46..45a27ecfa6 100644 --- a/static/bidder-info/progx.yaml +++ b/static/bidder-info/progx.yaml @@ -1,9 +1,12 @@ -aliasOf: "vidazoo" -endpoint: "https://exchange.programmaticx.ai/openrtb/" +aliasOf: 'teqblaze' +endpoint: "https://us-east.progrtb.com/pserver" maintainer: email: "pxteam@programmaticx.ai" gvlVendorID: 1344 userSync: + redirect: + url: "https://sync.progrtb.com/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "[UID]" iframe: - url: https://sync.programmaticx.ai/api/user/html/685297194d85991a5e6e36dd?pbs=true&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}} - userMacro: ${userId} \ No newline at end of file + url: "https://sync.progrtb.com/pbserverIframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&pbserverUrl={{.RedirectURL}}" + userMacro: "[UID]" diff --git a/static/bidder-info/proxistore.yaml b/static/bidder-info/proxistore.yaml new file mode 100644 index 0000000000..49fb1828cf --- /dev/null +++ b/static/bidder-info/proxistore.yaml @@ -0,0 +1,29 @@ +endpoint: "https://api.proxistore.com/v3/rtb/openrtb" +endpointCompression: gzip +geoscope: + - EEA +maintainer: + email: support@proxistore.com +gvlVendorID: 418 +openrtb: + version: 2.6 +capabilities: + app: + mediaTypes: + - banner + - video + - native + - audio + site: + mediaTypes: + - banner + - video + - native + - audio +userSync: + redirect: + url: https://abs.proxistore.com/v3/rtb/sync/prebid-server/redirect?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect={{.RedirectURL}} + userMacro: $UID + iframe: + url: https://abs.proxistore.com/v3/rtb/sync/prebid-server/iframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect={{.RedirectURL}} + userMacro: $UID \ No newline at end of file diff --git a/static/bidder-info/radiantfusion.yaml b/static/bidder-info/radiantfusion.yaml new file mode 100644 index 0000000000..583fa8762a --- /dev/null +++ b/static/bidder-info/radiantfusion.yaml @@ -0,0 +1,2 @@ +endpoint: "https://radiantfusion-prebid.attekmi.co/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +aliasOf: "smarthub" diff --git a/static/bidder-info/reklamup.yaml b/static/bidder-info/reklamup.yaml new file mode 100644 index 0000000000..beb03cbcd3 --- /dev/null +++ b/static/bidder-info/reklamup.yaml @@ -0,0 +1,23 @@ +aliasOf: "teqblaze" +endpoint: "https://node.reklamup.com/pserver" +maintainer: + email: "support@reklamup.com" +gvlVendorID: 1619 +capabilities: + site: + mediaTypes: + - banner + - video + - native + app: + mediaTypes: + - banner + - video + - native +userSync: + redirect: + url: "https://usersync.reklamup.com/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "[UID]" + iframe: + url: "https://usersync.reklamup.com/pbserverIframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&pbserverUrl={{.RedirectURL}}" + userMacro: "[UID]" diff --git a/static/bidder-info/resetdigital.yaml b/static/bidder-info/resetdigital.yaml index db4e70ae76..0651791dc0 100644 --- a/static/bidder-info/resetdigital.yaml +++ b/static/bidder-info/resetdigital.yaml @@ -1,14 +1,23 @@ -endpoint: http://b-us-east14.resetdigital.co:9001 +endpoint: https://prebid.resetdigital.co +endpointCompression: gzip maintainer: email: biddersupport@resetdigital.co +gvlVendorID: 1162 capabilities: site: mediaTypes: - - banner - - video - - audio -gvlVendorID: 1162 -userSync: + - banner + - video + - native + - audio + app: + mediaTypes: + - banner + - video + - native + - audio + +usersync: redirect: - url: https://sync.resetdigital.co/csync?redir={{.RedirectURL}} - userMacro: '$USER_ID' + url: "https://sync.resetdigital.co/usersync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" + userMacro: "$UID" diff --git a/static/bidder-info/rtbdemand.yaml b/static/bidder-info/rtbdemand.yaml new file mode 100644 index 0000000000..9f3edf6d48 --- /dev/null +++ b/static/bidder-info/rtbdemand.yaml @@ -0,0 +1,2 @@ +endpoint: "http://ads-pbs.ads-rtbdemand.com/openrtb/{{.PublisherID}}?host={{.Host}}" +aliasOf: "limelightDigital" \ No newline at end of file diff --git a/static/bidder-info/rtbstack.yaml b/static/bidder-info/rtbstack.yaml new file mode 100644 index 0000000000..34f02f0e97 --- /dev/null +++ b/static/bidder-info/rtbstack.yaml @@ -0,0 +1,19 @@ +endpoint: "https://{{.Region}}-adx-admixer.rtb-stack.com/pbs?ssp={{.SspID}}&endpoint={{.ZoneID}}&client={{.PartnerId}}" +maintainer: + email: "prebid@admixer.net" +gvlVendorID: 511 +openrtb: + version: "2.6" +capabilities: + site: + mediaTypes: + - banner + - video + - native + - audio + app: + mediaTypes: + - banner + - video + - native + - audio \ No newline at end of file diff --git a/static/bidder-info/scalibur.yaml b/static/bidder-info/scalibur.yaml new file mode 100644 index 0000000000..06f84058a0 --- /dev/null +++ b/static/bidder-info/scalibur.yaml @@ -0,0 +1,25 @@ +endpoint: "https://srv.scalibur.io/adserver/ortb?type=prebid-server" +# Leave disabled: false → adapter enabled +endpointCompression: gzip +disabled: false +maintainer: + email: "support@scalibur.io" +gvlVendorID: 1471 +openrtb: + version: 2.6 + gpp-supported: true +capabilities: + site: + mediaTypes: + - banner + - video + app: + mediaTypes: + - banner + - video +userSync: + iframe: + url: "https://srv.scalibur.io/adserver/sync?type=iframe&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" + userMacro: "[PBS_UID]" + supports: + - iframe \ No newline at end of file diff --git a/static/bidder-info/screencore.yaml b/static/bidder-info/screencore.yaml index 67777a1378..4dd3a19f79 100644 --- a/static/bidder-info/screencore.yaml +++ b/static/bidder-info/screencore.yaml @@ -1,14 +1,14 @@ -endpoint: 'http://h1.screencore.io/?kp={{.AccountID}}&kn={{.SourceId}}' +aliasOf: "teqblaze" +# We have the following regional endpoint domains: 'taqus' - for US_EAST, 'taqeu' - for EU, 'taqapac' - for APAC +# Please deploy this config in each of your datacenters with the appropriate regional subdomain +endpoint: 'https://REGION.screencore.io/pserver' maintainer: email: 'connect@screencore.io' -capabilities: - app: - mediaTypes: - - banner - - video - - native - site: - mediaTypes: - - banner - - video - - native +gvlVendorID: 1473 +userSync: + redirect: + url: "https://cs.screencore.io/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&coppa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "[UID]" + iframe: + url: "https://cs.screencore.io/pbserverIframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&pbserverUrl={{.RedirectURL}}" + userMacro: "[UID]" diff --git a/static/bidder-info/seedtag.yaml b/static/bidder-info/seedtag.yaml index 20df62ff0e..20dd7dfd5c 100644 --- a/static/bidder-info/seedtag.yaml +++ b/static/bidder-info/seedtag.yaml @@ -10,5 +10,5 @@ capabilities: - banner userSync: iframe: - url: "https://s.seedtag.com/cs/cookiesync/prebid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&usp_consent={{.USPrivacy}}&redirect={{.RedirectURL}}" + url: "https://s.seedtag.com/cs/cookiesync/prebid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&usp_consent={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redirect={{.RedirectURL}}" userMacro: "$UID" diff --git a/static/bidder-info/selectmedia.yaml b/static/bidder-info/selectmedia.yaml new file mode 100644 index 0000000000..752c5ddb6f --- /dev/null +++ b/static/bidder-info/selectmedia.yaml @@ -0,0 +1,26 @@ +disabled: true +# We have the following regional endpoint domains: 'us-east' - for US_EAST, 'eu' - for EU +# Please deploy this config in each of your datacenters with the appropriate regional subdomain +aliasOf: "teqblaze" +endpoint: "https://#{REGION}#.zxyvrtd.com/pserver" +gvlVendorID: 775 +maintainer: + email: "prebid@selectmedia.asia" +capabilities: + site: + mediaTypes: + - banner + - video + - native + app: + mediaTypes: + - banner + - video + - native +userSync: + redirect: + url: "https://sync.zxyvrtd.com/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "[UID]" + iframe: + url: "https://sync.zxyvrtd.com/pbserverIframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&pbserverUrl={{.RedirectURL}}" + userMacro: "[UID]" \ No newline at end of file diff --git a/static/bidder-info/showheroes-bs.yaml b/static/bidder-info/showheroes-bs.yaml index 4b49a60f18..7143e05aed 100644 --- a/static/bidder-info/showheroes-bs.yaml +++ b/static/bidder-info/showheroes-bs.yaml @@ -1 +1,2 @@ -aliasOf: "showheroes" \ No newline at end of file +aliasOf: "showheroes" +gvlVendorID: 111 \ No newline at end of file diff --git a/static/bidder-info/showheroes.yaml b/static/bidder-info/showheroes.yaml index 29296ecd91..0586f34ca4 100644 --- a/static/bidder-info/showheroes.yaml +++ b/static/bidder-info/showheroes.yaml @@ -2,6 +2,7 @@ endpoint: "https://ads.viralize.tv/openrtb2/auction/" maintainer: email: tech@showheroes.com gvlVendorID: 111 +endpointCompression: gzip openrtb: version: 2.6 capabilities: diff --git a/static/bidder-info/showheroesBs.yaml b/static/bidder-info/showheroesBs.yaml index 4b49a60f18..7143e05aed 100644 --- a/static/bidder-info/showheroesBs.yaml +++ b/static/bidder-info/showheroesBs.yaml @@ -1 +1,2 @@ -aliasOf: "showheroes" \ No newline at end of file +aliasOf: "showheroes" +gvlVendorID: 111 \ No newline at end of file diff --git a/static/bidder-info/smarthub.yaml b/static/bidder-info/smarthub.yaml index 43e12ae257..a0941a08e9 100644 --- a/static/bidder-info/smarthub.yaml +++ b/static/bidder-info/smarthub.yaml @@ -1,4 +1,4 @@ -endpoint: "https://prebid.attekmi.com/pbserver?partnerName={{.Host}}&seat={{.AccountID}}&token={{.SourceId}}" +endpoint: "https://prebid.attekmi.co/pbserver?partnerName={{.Host}}&seat={{.AccountID}}&token={{.SourceId}}" maintainer: email: "prebid@attekmi.com" capabilities: diff --git a/static/bidder-info/smb.yaml b/static/bidder-info/smb.yaml new file mode 100644 index 0000000000..64d47d793d --- /dev/null +++ b/static/bidder-info/smb.yaml @@ -0,0 +1,16 @@ +aliasOf: "teqblaze" +endpoint: "http://be.smartbid.ai/pserver" +maintainer: + email: "support@smartbid.ai" +capabilities: + site: + mediaTypes: + - banner + - video + - native + + app: + mediaTypes: + - banner + - video + - native \ No newline at end of file diff --git a/static/bidder-info/smootai.yaml b/static/bidder-info/smootai.yaml new file mode 100644 index 0000000000..4185dc0478 --- /dev/null +++ b/static/bidder-info/smootai.yaml @@ -0,0 +1,2 @@ +endpoint: "http://ads-pbs.ads-smoot.com/openrtb/{{.PublisherID}}?host={{.Host}}" +aliasOf: "limelightDigital" \ No newline at end of file diff --git a/static/bidder-info/sparteo.yaml b/static/bidder-info/sparteo.yaml index 1ad61ab072..f9270be721 100644 --- a/static/bidder-info/sparteo.yaml +++ b/static/bidder-info/sparteo.yaml @@ -16,5 +16,4 @@ capabilities: endpoint: "https://bid.sparteo.com/s2s-auction" userSync: iframe: - url: "https://sync.sparteo.com/s2s_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect_url={{.RedirectURL}}" - supportCors: true \ No newline at end of file + url: "https://sync.sparteo.com/s2s_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redirect_url={{.RedirectURL}}" diff --git a/static/bidder-info/stackadapt.yaml b/static/bidder-info/stackadapt.yaml new file mode 100644 index 0000000000..6ba316fe21 --- /dev/null +++ b/static/bidder-info/stackadapt.yaml @@ -0,0 +1,24 @@ +endpoint: "https://pbs.srv.stackadapt.com/br?publisher_id={{.PublisherID}}&supply_id={{.SupplyId}}" +endpointCompression: gzip +maintainer: + email: pjs@stackadapt.com +gvlVendorID: 238 +openrtb: + gpp-supported: true +capabilities: + site: + mediaTypes: + - banner + - video + - native + - audio + app: + mediaTypes: + - banner + - video + - native + - audio +userSync: + redirect: + url: "https://sync.srv.stackadapt.com/sync?nid=pbs&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redirect={{.RedirectURL}}" + userMacro: "$UID" \ No newline at end of file diff --git a/static/bidder-info/streamkey.yaml b/static/bidder-info/streamkey.yaml index 20510ceac6..463abd64be 100644 --- a/static/bidder-info/streamkey.yaml +++ b/static/bidder-info/streamkey.yaml @@ -2,6 +2,7 @@ aliasOf: adtelligent endpoint: "http://ghb.hb.streamkey.net/pbs/ortb" maintainer: email: "contact@streamkey.tv" +gvlVendorID: 410 capabilities: app: mediaTypes: diff --git a/static/bidder-info/synapseHX.yaml b/static/bidder-info/synapseHX.yaml new file mode 100644 index 0000000000..2424fd76e4 --- /dev/null +++ b/static/bidder-info/synapseHX.yaml @@ -0,0 +1,21 @@ +endpoint: "https://rtb.hx.compasonline.com/pbs" +maintainer: + email: prebid@compas-inc.com +openrtb: + version: 2.6 +capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video +userSync: + redirect: + url: "https://sync.hx.compasonline.com/pbserver/image?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redirect={{.RedirectURL}}" + userMacro: "${VISITOR_ID}" + iframe: + url: "https://sync.hx.compasonline.com/pbserver/iframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redirect={{.RedirectURL}}" + userMacro: "${VISITOR_ID}" diff --git a/static/bidder-info/tadvertising_blis.yaml b/static/bidder-info/tadvertising_blis.yaml new file mode 100644 index 0000000000..115a4f752b --- /dev/null +++ b/static/bidder-info/tadvertising_blis.yaml @@ -0,0 +1,21 @@ +endpoint: "https://prebid-blis.tads.xplosion.de/bid" +endpointCompression: gzip +geoscope: + - GLOBAL +maintainer: + email: dev@emetriq.com +gvlVendorID: 213 +modifyingVastXmlAllowed: true +openrtb: + version: 2.6 +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native \ No newline at end of file diff --git a/static/bidder-info/tagoras.yaml b/static/bidder-info/tagoras.yaml index c40aaa2a04..f8f94a456d 100644 --- a/static/bidder-info/tagoras.yaml +++ b/static/bidder-info/tagoras.yaml @@ -2,6 +2,7 @@ aliasOf: "vidazoo" endpoint: "https://exchange.tagoras.io/openrtb/" maintainer: email: "prebid@tagoras.io" +gvlVendorID: 1450 userSync: iframe: url: https://sync.tagoras.io/api/user/html/6819bdc3e6bb44545c55f843?pbs=true&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}} diff --git a/static/bidder-info/targetVideo.yaml b/static/bidder-info/targetVideo.yaml new file mode 100644 index 0000000000..decc110db3 --- /dev/null +++ b/static/bidder-info/targetVideo.yaml @@ -0,0 +1,17 @@ +endpoint: "https://pbs.prebrid.tv/openrtb2/auction" +geoscope: + - global +maintainer: + email: "contact@target-video.com" +gvlVendorID: 786 +capabilities: + app: + mediaTypes: + - video + site: + mediaTypes: + - video +userSync: + redirect: + url: "https://pbs.prebrid.tv/user_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redirect={{.RedirectURL}}" + userMacro: "[TVUID]" diff --git a/static/bidder-info/teal.yaml b/static/bidder-info/teal.yaml new file mode 100644 index 0000000000..6f6bf74dd9 --- /dev/null +++ b/static/bidder-info/teal.yaml @@ -0,0 +1,27 @@ +endpoint: "https://a.bids.ws/openrtb2/auction" +maintainer: + email: prebid@teal.works +gvlVendorID: 1378 +endpointCompression: gzip +modifyingVastXmlAllowed: true +geoscope: + - global +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native +userSync: + key: "teal" + iframe: + url: "https://bids.ws/load-pbs.html?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redirect_url={{.RedirectURL}}" +openrtb: + version: 2.6 + multiformat-supported: true + gpp-supported: true diff --git a/static/bidder-info/thetradedesk.yaml b/static/bidder-info/thetradedesk.yaml index 7fe4864354..623154f593 100644 --- a/static/bidder-info/thetradedesk.yaml +++ b/static/bidder-info/thetradedesk.yaml @@ -8,11 +8,13 @@ capabilities: - banner - video - native + - audio site: mediaTypes: - banner - video - native + - audio userSync: # TheTradeDesk supports user syncing, but requires configuration by the host. Contact a technical account manager # or this bidder directly at the email address in this file to ask about enabling user sync. @@ -21,4 +23,5 @@ userSync: - iframe openrtb: gpp-supported: true + version: 2.6 endpointCompression: "GZIP" diff --git a/static/bidder-info/tredio.yaml b/static/bidder-info/tredio.yaml index fd8ac68689..d4a4e6c5be 100644 --- a/static/bidder-info/tredio.yaml +++ b/static/bidder-info/tredio.yaml @@ -1,4 +1,4 @@ -endpoint: "https://tredio-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +endpoint: "https://tredio-prebid.attekmi.co/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" aliasOf: "smarthub" userSync: supports: diff --git a/static/bidder-info/trustx.yaml b/static/bidder-info/trustx.yaml index 1c60ac34c2..878d1d1d23 100644 --- a/static/bidder-info/trustx.yaml +++ b/static/bidder-info/trustx.yaml @@ -1,9 +1,19 @@ -aliasOf: grid +endpoint: "https://ads.trustx.org/pbs" maintainer: - email: "grid-tech@themediagrid.com" -gvlVendorID: 686 + email: "prebid@trustx.org" +capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video userSync: + iframe: + url: "https://static.cdn.trustx.org/x/user_sync.html?source=pbs&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redirect={{.RedirectURL}}" + userMacro: "$UID" redirect: - url: "https://x.bidswitch.net/check_uuid/{{.RedirectURL}}?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}" - userMacro: "${BSW_UUID}" - \ No newline at end of file + url: "https://sync.trustx.org/usync-pbs?us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redirect={{.RedirectURL}}" + userMacro: "$UID" diff --git a/static/bidder-info/ttd.yaml b/static/bidder-info/ttd.yaml index db055e1a75..78ed8c79b5 100644 --- a/static/bidder-info/ttd.yaml +++ b/static/bidder-info/ttd.yaml @@ -1 +1,2 @@ aliasOf: thetradedesk +gvlVendorID: 21 diff --git a/static/bidder-info/verben.yaml b/static/bidder-info/verben.yaml new file mode 100644 index 0000000000..a5b9cfed3d --- /dev/null +++ b/static/bidder-info/verben.yaml @@ -0,0 +1,4 @@ +aliasOf: "teqblaze" +endpoint: "https://east-node.verben.com/pserver" +maintainer: + email: "support_trading@verben.com" diff --git a/static/bidder-info/vimayx.yaml b/static/bidder-info/vimayx.yaml deleted file mode 100644 index 567d95c8c2..0000000000 --- a/static/bidder-info/vimayx.yaml +++ /dev/null @@ -1,2 +0,0 @@ -endpoint: "https://vimayx-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" -aliasOf: "smarthub" diff --git a/static/bidder-info/waardex_ak.yaml b/static/bidder-info/waardex_ak.yaml new file mode 100644 index 0000000000..36dce9a134 --- /dev/null +++ b/static/bidder-info/waardex_ak.yaml @@ -0,0 +1,8 @@ +aliasOf: adkernel +userSync: + redirect: + url: "https://sync.adkernel.com/user-sync?t=image&zone=313534&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&r={{.RedirectURL}}" + userMacro: "{UID}" + iframe: + url: "https://sync.adkernel.com/user-sync?t=iframe&zone=313534&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&r={{.RedirectURL}}" + userMacro: "{UID}" \ No newline at end of file diff --git a/static/bidder-info/yahooAds.yaml b/static/bidder-info/yahooAds.yaml index c53d1b14e0..2d86a0f27a 100644 --- a/static/bidder-info/yahooAds.yaml +++ b/static/bidder-info/yahooAds.yaml @@ -2,6 +2,8 @@ endpoint: "https://s2shb.ssp.yahoo.com/admax/bid/partners/PBS" maintainer: email: "prebid-tech-team@yahooinc.com" gvlVendorID: 25 +openrtb: + version: "2.6" capabilities: app: mediaTypes: diff --git a/static/bidder-info/yahooAdvertising.yaml b/static/bidder-info/yahooAdvertising.yaml index f9f34fbfbd..68037fb68f 100644 --- a/static/bidder-info/yahooAdvertising.yaml +++ b/static/bidder-info/yahooAdvertising.yaml @@ -1,4 +1,5 @@ aliasOf: yahooAds +gvlVendorID: 25 userSync: # yahooAdvertising supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. diff --git a/static/bidder-info/yahoossp.yaml b/static/bidder-info/yahoossp.yaml index 81695624df..132bef5a83 100644 --- a/static/bidder-info/yahoossp.yaml +++ b/static/bidder-info/yahoossp.yaml @@ -1,6 +1,7 @@ aliasOf: yahooAds maintainer: email: "hb-fe-tech@oath.com" +gvlVendorID: 25 userSync: # yahoossp supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. diff --git a/static/bidder-info/yobee.yaml b/static/bidder-info/yobee.yaml index 28ce00e79d..94023eef0b 100644 --- a/static/bidder-info/yobee.yaml +++ b/static/bidder-info/yobee.yaml @@ -1,3 +1,4 @@ aliasOf: "admatic" maintainer: - email: "adops@yobee.it" \ No newline at end of file + email: "adops@yobee.it" +gvlVendorID: 1281 \ No newline at end of file diff --git a/static/bidder-params/acuityads.json b/static/bidder-params/acuityads.json index bae86ad210..b5ccdf67d2 100644 --- a/static/bidder-params/acuityads.json +++ b/static/bidder-params/acuityads.json @@ -7,7 +7,8 @@ "host": { "type": "string", "description": "Network host to send request", - "minLength": 1 + "minLength": 1, + "pattern": "^[a-zA-Z0-9.-]+(:[0-9]+)?$" }, "accountid": { "type": "string", @@ -15,5 +16,8 @@ "minLength": 1 } }, - "required": ["host", "accountid"] -} \ No newline at end of file + "required": [ + "host", + "accountid" + ] +} diff --git a/static/bidder-params/adhese.json b/static/bidder-params/adhese.json index 14234a8bd1..ac6576c81d 100644 --- a/static/bidder-params/adhese.json +++ b/static/bidder-params/adhese.json @@ -7,6 +7,7 @@ "account": { "type": "string", "minLength": 1, + "pattern": "^[a-zA-Z0-9.-]+$", "description": "Your Adhese account name. If unknown, please contact your sales rep" }, "location": { diff --git a/static/bidder-params/adocean.json b/static/bidder-params/adocean.json deleted file mode 100644 index a3c5cbc95d..0000000000 --- a/static/bidder-params/adocean.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "AdOcean Adapter Params", - "description": "A schema which validates params accepted by the AdOcean adapter", - "type": "object", - "properties": { - "emiter": { - "type": "string", - "description": "Deprecated, use emitterPrefix instead. AdOcean emiter", - "pattern": ".+" - }, - "emitterPrefix": { - "type": "string", - "description": "AdOcean emitter prefix", - "pattern": "^[\\w\\-]+$" - }, - "masterId": { - "type": "string", - "description": "Master's id", - "pattern": "^[\\w.]+$" - }, - "slaveId": { - "type": "string", - "description": "Slave's id", - "pattern": "^adocean[\\w.]+$" - } - }, - "oneOf": [ - { "required": ["emiter", "masterId", "slaveId"] }, - { "required": ["emitterPrefix", "masterId", "slaveId"] } - ] -} diff --git a/static/bidder-params/adot.json b/static/bidder-params/adot.json index e82b17be8d..45caca4da8 100644 --- a/static/bidder-params/adot.json +++ b/static/bidder-params/adot.json @@ -14,7 +14,8 @@ }, "publisherPath": { "type": "string", - "description": "An optional path used in the bid endpoint" + "enum": ["/hubvisor", "/spotx"], + "description": "An optional path used in the bid endpoint. Only '/hubvisor' and '/spotx' are allowed." } }, "required": [] diff --git a/static/bidder-params/ads_interactive.json b/static/bidder-params/ads_interactive.json deleted file mode 100644 index 6a750b9c18..0000000000 --- a/static/bidder-params/ads_interactive.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Ads Interactive Adapter Params", - "description": "A schema which validates params accepted by the Ads Interactive adapter", - "type": "object", - "properties": { - "placementId": { - "type": "string", - "minLength": 1, - "description": "Placement ID" - }, - "endpointId": { - "type": "string", - "minLength": 1, - "description": "Endpoint ID" - } - }, - "oneOf": [ - { "required": ["placementId"] }, - { "required": ["endpointId"] } - ] -} \ No newline at end of file diff --git a/static/bidder-params/adsinteractive.json b/static/bidder-params/adsinteractive.json deleted file mode 100644 index 662c7362ba..0000000000 --- a/static/bidder-params/adsinteractive.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Adsinteractive Adapter Params", - "description": "Adsinteractive Bidder Parameter Schema", - "type": "object", - "properties": { - "adUnit": { - "type": "string", - "description": "ad unit name" - } - }, - "required": ["adUnit"] -} diff --git a/static/bidder-params/alliance_gravity.json b/static/bidder-params/alliance_gravity.json new file mode 100644 index 0000000000..71135195ba --- /dev/null +++ b/static/bidder-params/alliance_gravity.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Alliance Gravity Adapter Params", + "description": "A schema which validates params accepted by the Alliance Gravity adapter", + "type": "object", + "properties": { + "srid": { + "type": "string", + "description": "Stored request ID", + "minLength": 1 + } + }, + + "required": ["srid"] +} diff --git a/static/bidder-params/beop.json b/static/bidder-params/beop.json new file mode 100644 index 0000000000..8b34ac91f7 --- /dev/null +++ b/static/bidder-params/beop.json @@ -0,0 +1,33 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "BeOp Adapter Params", + "description": "A schema which validates params accepted by the BeOp adapter", + "type": "object", + "properties": { + "pid": { + "type": "string", + "description": "Beop publisher ID" + }, + "nid": { + "type": "string", + "description": "Beop Network ID" + }, + "ntpnid": { + "type": "string", + "description": "Network partner ID" + } + }, + "oneOf": [ + { + "required": [ + "pid" + ] + }, + { + "required": [ + "nid", + "ntpnid" + ] + } + ] +} diff --git a/static/bidder-params/bidmachine.json b/static/bidder-params/bidmachine.json index 819dc9b7e2..752461589a 100644 --- a/static/bidder-params/bidmachine.json +++ b/static/bidder-params/bidmachine.json @@ -1,28 +1,29 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Bidmachine Adapter Params", - "description": "A schema which validates params accepted by the Kidoz adapter", - "type": "object", - "properties": { - "host": { - "type": "string", - "minLength": 1, - "description": "Host" - }, - "path": { - "type": "string", - "minLength": 1, - "description": "URL path" - }, - "seller_id": { - "type": "string", - "minLength": 1, - "description": "Seller Identifier" - } + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Bidmachine Adapter Params", + "description": "A schema which validates params accepted by the Kidoz adapter", + "type": "object", + "properties": { + "host": { + "type": "string", + "minLength": 1, + "description": "Host", + "pattern": "^[a-zA-Z0-9.-]+(:[0-9]+)?$" }, - "required": [ - "host", - "path", - "seller_id" - ] + "path": { + "type": "string", + "minLength": 1, + "description": "URL path" + }, + "seller_id": { + "type": "string", + "minLength": 1, + "description": "Seller Identifier" + } + }, + "required": [ + "host", + "path", + "seller_id" + ] } diff --git a/static/bidder-params/adoppler.json b/static/bidder-params/elementaltv.json similarity index 66% rename from static/bidder-params/adoppler.json rename to static/bidder-params/elementaltv.json index 508eef478c..fbe36a9606 100644 --- a/static/bidder-params/adoppler.json +++ b/static/bidder-params/elementaltv.json @@ -1,16 +1,12 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Adoppler Adapter Params", - "description": "A schema which validates params accepted by the Adoppler adapter", + "title": "ElementalTV Adapter Params", + "description": "A schema which validates params accepted by the ElementalTV adapter", "type": "object", "properties": { "adunit": { "type": "string", "description": "AdUnit to bid against to." - }, - "client": { - "type": "string", - "description": "Client name." } }, "required": ["adunit"] diff --git a/static/bidder-params/eskimi.json b/static/bidder-params/eskimi.json new file mode 100644 index 0000000000..a69a8da81e --- /dev/null +++ b/static/bidder-params/eskimi.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Eskimi Adapter Params", + "description": "A schema which validates params accepted by the Eskimi adapter", + "type": "object", + "additionalProperties": false, + "properties": { + "placementId": { + "type": "integer", + "minimum": 1, + "description": "The Eskimi placement ID" + }, + "bidFloor": { + "type": "number", + "minimum": 0, + "description": "The minimum bid floor (USD unless bidFloorCur is set)" + }, + "bidFloorCur": { + "type": "string", + "description": "The currency of the bid floor" + }, + "bcat": { + "type": "array", + "items": { "type": "string" }, + "description": "Blocked IAB advertiser categories" + }, + "badv": { + "type": "array", + "items": { "type": "string" }, + "description": "Blocked advertiser domains" + }, + "bapp": { + "type": "array", + "items": { "type": "string" }, + "description": "Blocked app bundles" + }, + "battr": { + "type": "array", + "items": { "type": "integer", "minimum": 1, "maximum": 17 }, + "description": "Blocked creative attributes (OpenRTB List 5.3)" + } + }, + "required": ["placementId"] +} diff --git a/static/bidder-params/ezoic.json b/static/bidder-params/ezoic.json new file mode 100644 index 0000000000..ecd916a461 --- /dev/null +++ b/static/bidder-params/ezoic.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Ezoic Adapter Params", + "description": "A schema which validates params accepted by the Ezoic adapter", + "type": "object", + "properties": { + "placementId": { + "type": "string", + "description": "Optional placement identifier assigned during Ezoic onboarding" + } + }, + "required": [] +} diff --git a/static/bidder-params/insticator.json b/static/bidder-params/insticator.json index 358ec37f57..7e6f8d635d 100644 --- a/static/bidder-params/insticator.json +++ b/static/bidder-params/insticator.json @@ -3,7 +3,7 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "Insticator Adapter Params", "description": "A schema which validates params accepted by Insticator", - + "type": "object", "properties": { "adUnitId": { diff --git a/static/bidder-params/gothamads.json b/static/bidder-params/intenze.json similarity index 84% rename from static/bidder-params/gothamads.json rename to static/bidder-params/intenze.json index 030d43eb31..1d42a6535f 100644 --- a/static/bidder-params/gothamads.json +++ b/static/bidder-params/intenze.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Gothamads Adapter Params", - "description": "A schema which validates params accepted by the Gothamads adapter", + "title": "Intenze Adapter Params", + "description": "A schema which validates params accepted by the Intenze adapter", "type": "object", "properties": { "accountId": { diff --git a/static/bidder-params/intertech.json b/static/bidder-params/intertech.json deleted file mode 100644 index 8b1e3daa6c..0000000000 --- a/static/bidder-params/intertech.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Intertech Adapter Params", - "description": "A schema which validates params accepted by the Intertech adapter", - "type": "object", - "properties": { - "page_id": { - "type": "integer", - "minLength": 1, - "description": "Special Page Id provided by Intertech Manager" - }, - "imp_id": { - "type": "integer", - "minLength": 1, - "description": "Special identifier provided by Intertech Manager" - } - }, - "required": - ["page_id", - "imp_id"] -} \ No newline at end of file diff --git a/static/bidder-params/kayzen.json b/static/bidder-params/kayzen.json index f2256c6b02..8383fac679 100644 --- a/static/bidder-params/kayzen.json +++ b/static/bidder-params/kayzen.json @@ -8,6 +8,7 @@ "zone": { "type": "string", "minLength": 1, + "pattern": "^[a-zA-Z0-9.-]+$", "description": "Zone ID" }, "exchange": { diff --git a/static/bidder-params/missena.json b/static/bidder-params/missena.json index f06b9cf466..9e17a07f08 100644 --- a/static/bidder-params/missena.json +++ b/static/bidder-params/missena.json @@ -13,9 +13,9 @@ "type": "string", "description": "Placement Type (Sticky, Header, ...)" }, - "test": { + "sample": { "type": "string", - "description": "Test Mode" + "description": "Sample" }, "formats": { "type": "array", diff --git a/static/bidder-params/nativo.json b/static/bidder-params/nativo.json index 0a8139a083..fbe4685b55 100644 --- a/static/bidder-params/nativo.json +++ b/static/bidder-params/nativo.json @@ -3,5 +3,10 @@ "title": "Nativo Adapter Params", "description": "A schema which validates params accepted by the Nativo adapter", "type": "object", - "properties": {} + "properties": { + "placementId": { + "type": ["integer", "string"], + "description": "Placement ID" + } + } } \ No newline at end of file diff --git a/static/bidder-params/pixfuture.json b/static/bidder-params/pixfuture.json new file mode 100644 index 0000000000..ffff62099a --- /dev/null +++ b/static/bidder-params/pixfuture.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "PixFuture Adapter Params", + "description": "A schema which validates params accepted by the PixFuture adapter", + "type": "object", + "properties": { + "pix_id": { + "type": "string", + "description": "PixFuture placement ID", + "minLength": 1 + } + }, + "required": [ + "pix_id" + ], + "additionalProperties": false +} \ No newline at end of file diff --git a/static/bidder-params/proxistore.json b/static/bidder-params/proxistore.json new file mode 100644 index 0000000000..d9360a49ce --- /dev/null +++ b/static/bidder-params/proxistore.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Proxistore Adapter Params", + "description": "A schema which validates params accepted by the Proxistore adapter", + "type": "object", + "properties": { + "website": { + "type": "string", + "minLength": 1, + "description": "Publisher website identifier" + }, + "language": { + "type": "string", + "minLength": 1, + "description": "Language code (e.g., 'fr', 'en')" + } + }, + "required": ["website", "language"] +} \ No newline at end of file diff --git a/static/bidder-params/rediads.json b/static/bidder-params/rediads.json index 85c9e545a2..dbca954bba 100644 --- a/static/bidder-params/rediads.json +++ b/static/bidder-params/rediads.json @@ -11,7 +11,8 @@ "type": "string" }, "endpoint": { - "type": "string" + "type": "string", + "pattern": "^[a-zA-Z0-9.-]+$" } }, "required": ["account_id"] diff --git a/static/bidder-params/relevantdigital.json b/static/bidder-params/relevantdigital.json index 5f88d85fe5..6c6cdca051 100644 --- a/static/bidder-params/relevantdigital.json +++ b/static/bidder-params/relevantdigital.json @@ -1,29 +1,34 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Relevant Digital Adapter Params", - "description": "A schema which validates params accepted by the Relevant Digital adapter", - "type": "object", - "properties": { - "accountId": { - "type": "string", - "description": "An ID which identifies the Relevant Digital account ID" - }, - "placementId": { - "type": "string", - "description": "An ID which identifies the Relevant Digital placement ID" - }, - "pbsHost": { - "type": "string", - "description": "Prebid Server Host supplied by Relevant Digital" - }, - "pbsBufferMs": { - "type": "number", - "description": "TMax buffer, default is 250" - } + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Relevant Digital Adapter Params", + "description": "A schema which validates params accepted by the Relevant Digital adapter", + "type": "object", + "properties": { + "accountId": { + "type": "string", + "description": "An ID which identifies the Relevant Digital account ID" }, - "required": [ - "accountId", - "placementId", - "pbsHost" - ] + "placementId": { + "type": "string", + "description": "An ID which identifies the Relevant Digital placement ID" + }, + "pbsHost": { + "type": "string", + "description": "Prebid Server Host supplied by Relevant Digital", + "pattern": "^(https?://)?[a-zA-Z0-9.-]+(:[0-9]+)?$" + }, + "pbsBufferMs": { + "type": "number", + "description": "TMax buffer, default is 250" + }, + "useSourceBidderCode": { + "type": "boolean", + "description": "Use the bidder code of the actual server-side bidder in bid responses" + } + }, + "required": [ + "accountId", + "placementId", + "pbsHost" + ] } diff --git a/static/bidder-params/resetdigital.json b/static/bidder-params/resetdigital.json index 4d0538893f..dc79816ce6 100644 --- a/static/bidder-params/resetdigital.json +++ b/static/bidder-params/resetdigital.json @@ -1,13 +1,15 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Reset Digital Adapter Params", - "description": "A schema which validates params accepted by the Reset Digital adapter", - "type": "object", - "properties": { - "placement_id": { - "type": "string", - "minLength": 1, - "description": "Placement ID for the Reset Digital ad unit. This is the identifier for the ad unit on the Reset Digital platform, and its optional" - } + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "ResetDigital Adapter Params", + "description": "A schema which validates params accepted by the ResetDigital adapter", + "type": "object", + "properties": { + "placement_id": { + "type": "string", + "description": "Placement ID provided by ResetDigital", + "minLength": 1 } + }, + "required": ["placement_id"], + "additionalProperties": false } diff --git a/static/bidder-params/rtbstack.json b/static/bidder-params/rtbstack.json new file mode 100644 index 0000000000..b5b90aefd0 --- /dev/null +++ b/static/bidder-params/rtbstack.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "RTBStack Adapter Params", + "description": "A schema which validates params accepted by the RTBStack adapter", + + "type": "object", + "properties": { + "route": { + "type": "string", + "minLength": 1, + "description": "Full route URL used to derive RTBStack endpoint (contains region, client, endpoint, ssp)." + }, + "tagId": { + "type": "string", + "description": "AdUnit tag id." + }, + "customParams": { + "type": "object", + "description": "Custom values for targeting." + } + }, + + "required": ["route", "tagId"] +} \ No newline at end of file diff --git a/static/bidder-params/scalibur.json b/static/bidder-params/scalibur.json new file mode 100644 index 0000000000..05a12e99f2 --- /dev/null +++ b/static/bidder-params/scalibur.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Scalibur Adapter Params", + "description": "A valid BidderParams object for the Scalibur adapter", + "type": "object", + "properties": { + "placementId": { + "type": "string", + "minLength": 1 + }, + "bidfloor": { + "type": "number", + "minimum": 0 + }, + "bidfloorcur": { + "type": "string" + } + }, + "required": [ + "placementId" + ] +} diff --git a/static/bidder-params/screencore.json b/static/bidder-params/screencore.json deleted file mode 100644 index 0a181b20f1..0000000000 --- a/static/bidder-params/screencore.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Screencore Adapter Params", - "description": "A schema which validates params accepted by the Screencore adapter", - "type": "object", - "properties": { - "accountId": { - "type": "string", - "description": "Account id", - "minLength": 1 - }, - "placementId": { - "type": "string", - "description": "Placement id", - "minLength": 1 - } - }, - "required": [ - "accountId", - "placementId" - ] -} \ No newline at end of file diff --git a/static/bidder-params/seedtag.json b/static/bidder-params/seedtag.json index 7f361c44f9..677fb9fba2 100644 --- a/static/bidder-params/seedtag.json +++ b/static/bidder-params/seedtag.json @@ -6,11 +6,26 @@ "properties": { "adUnitId": { "type": "string", - "description": "Ad Unit ID", + "description": "Ad Unit ID for the placement", "minLength": 1 + }, + "publisherId": { + "type": "string", + "description": "Publisher group ID for RON integration", + "minLength": 1 + }, + "integrationType": { + "type": "string", + "description": "Integration type. Use 'ronId' when integrating via publisherToken", + "enum": ["ronId"] } }, - "required": [ - "adUnitId" + "oneOf": [ + { + "required": ["adUnitId"] + }, + { + "required": ["publisherId", "integrationType"] + } ] -} \ No newline at end of file +} diff --git a/static/bidder-params/smartyads.json b/static/bidder-params/smartyads.json index 629fdde326..7a6518b263 100644 --- a/static/bidder-params/smartyads.json +++ b/static/bidder-params/smartyads.json @@ -6,7 +6,8 @@ "properties": { "host": { "type": "string", - "description": "Network host to send request" + "description": "Network host to send request", + "pattern": "^[a-zA-Z0-9.-]+(:[0-9]+)?$" }, "sourceid": { "type": "string", @@ -17,5 +18,9 @@ "description": "Account id" } }, - "required": ["host", "sourceid", "accountid"] -} \ No newline at end of file + "required": [ + "host", + "sourceid", + "accountid" + ] +} diff --git a/static/bidder-params/stackadapt.json b/static/bidder-params/stackadapt.json new file mode 100644 index 0000000000..68586ce451 --- /dev/null +++ b/static/bidder-params/stackadapt.json @@ -0,0 +1,42 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "StackAdapt Adapter Params", + "description": "A schema which validates params accepted by the StackAdapt adapter", + "type": "object", + "properties": { + "publisherId": { + "type": "string", + "minLength": 1, + "description": "An ID which identifies the publisher, provided by StackAdapt" + }, + "supplyId": { + "type": "string", + "minLength": 1, + "description": "An ID which identifies the supply source, provided by StackAdapt" + }, + "placementId": { + "type": "string", + "minLength": 1, + "description": "An ID which identifies the placement" + }, + "banner": { + "type": "object", + "description": "Banner-specific parameters", + "properties": { + "expdir": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "Expandable ad directions (1=left, 2=right, 3=up, 4=down, 5=fullscreen)" + } + } + }, + "bidfloor": { + "type": "number", + "minimum": 0, + "description": "Bid floor price in USD" + } + }, + "required": ["publisherId", "supplyId"] +} \ No newline at end of file diff --git a/static/bidder-params/synapseHX.json b/static/bidder-params/synapseHX.json new file mode 100644 index 0000000000..167a0b8f07 --- /dev/null +++ b/static/bidder-params/synapseHX.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Synapse HX Adapter Params", + "description": "A schema which validates params accepted by the Synapse HX adapter", + "type": "object", + "properties": { + "tenantId": { + "type": "string", + "description": "Synapse HX tenant identifier", + "minLength": 1 + } + }, + "required": ["tenantId"] +} diff --git a/static/bidder-params/tadvertising_blis.json b/static/bidder-params/tadvertising_blis.json new file mode 100644 index 0000000000..1c1d893cf3 --- /dev/null +++ b/static/bidder-params/tadvertising_blis.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "T-Advertising-Blis Adapter Params", + "description": "A schema which validates params accepted by the T-Advertising-Blis adapter", + "type": "object", + + "properties": { + "publisherId": { + "type": "string", + "minLength": 1, + "maxLength": 32, + "description": "Unique ID of the publisher/supply partner provided by T-Advertising" + } + }, + + "required": ["publisherId"] +} \ No newline at end of file diff --git a/static/bidder-params/tappx.json b/static/bidder-params/tappx.json index 77eb4eea93..f2dfe52c90 100644 --- a/static/bidder-params/tappx.json +++ b/static/bidder-params/tappx.json @@ -1,43 +1,47 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Tappx Adapter Params", - "description": "A schema which validates params accepted by the Tappx adapter", - "type": "object", - "properties": { - "host": { - "type": "string", - "description": "Tappx host" - }, - "tappxkey": { - "type": "string", - "description": "An ID which identifies the adunit" - }, - "mktag": { - "type": "string", - "description": "Minimum bid for this impression expressed in CPM (USD)" - }, - "endpoint": { - "type": "string", - "description": "Endpoint provided to publisher" - }, - "bidfloor": { - "type": "number", - "description": "Minimum bid for this impression expressed in CPM (USD)" - }, - "bcid": { - "type": "array", - "description": "Block list of CID", - "items": { - "type": "string" - } - }, - "bcrid": { - "type": "array", - "description": "Block list of CRID", - "items": { - "type": "string" - } - } - }, - "required": ["tappxkey","endpoint"] + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Tappx Adapter Params", + "description": "A schema which validates params accepted by the Tappx adapter", + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "Tappx host (DEPRECATED - unused)" + }, + "tappxkey": { + "type": "string", + "description": "An ID which identifies the adunit" + }, + "mktag": { + "type": "string", + "description": "Minimum bid for this impression expressed in CPM (USD)" + }, + "endpoint": { + "type": "string", + "minLength": 1, + "description": "Endpoint provided to publisher" + }, + "bidfloor": { + "type": "number", + "description": "Minimum bid for this impression expressed in CPM (USD)" + }, + "bcid": { + "type": "array", + "description": "Block list of CID", + "items": { + "type": "string" + } + }, + "bcrid": { + "type": "array", + "description": "Block list of CRID", + "items": { + "type": "string" + } + } + }, + "required": [ + "tappxkey", + "endpoint" + ] } diff --git a/static/bidder-params/targetVideo.json b/static/bidder-params/targetVideo.json new file mode 100644 index 0000000000..86c73b4bb7 --- /dev/null +++ b/static/bidder-params/targetVideo.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "TargetVideo Adapter Params", + "description": "A schema which validates params accepted by the TargetVideo adapter", + "type": "object", + "properties": { + "placementId": { + "type": ["integer", "string"], + "pattern": "^\\d+$", + "description": "An ID which identifies this placement of the impression" + } + }, + "required": ["placementId"] +} diff --git a/static/bidder-params/dxkulture.json b/static/bidder-params/teal.json similarity index 51% rename from static/bidder-params/dxkulture.json rename to static/bidder-params/teal.json index 858eefd22e..217dd083d3 100644 --- a/static/bidder-params/dxkulture.json +++ b/static/bidder-params/teal.json @@ -1,20 +1,21 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "DXKulture Adapter Params", - "description": "A schema which validates params accepted by the DXKulture adapter", + "title": "Teal Adapter Params", + "description": "A schema which validates params accepted by the Teal adapter", "type": "object", "properties": { - "publisherId": { + "account": { "type": "string", - "description": "The publisher id" + "minLength": 1, + "description": "Account ID" }, - "placementId": { + "placement": { "type": "string", - "description": "The placement id" + "minLength": 1, + "description": "Placement ID or name (optional)" } }, "required": [ - "publisherId", - "placementId" + "account" ] } diff --git a/static/bidder-params/tradplus.json b/static/bidder-params/tradplus.json index 2f568bad07..d463aa3f01 100644 --- a/static/bidder-params/tradplus.json +++ b/static/bidder-params/tradplus.json @@ -11,7 +11,8 @@ }, "zoneId": { "type": "string", - "description": "Zone ID" + "description": "Zone ID", + "pattern": "^[a-zA-Z0-9.-]*$" } }, "required": [ diff --git a/static/bidder-params/trafficgate.json b/static/bidder-params/trafficgate.json index 8b7ff3bee3..e6d8e7b793 100644 --- a/static/bidder-params/trafficgate.json +++ b/static/bidder-params/trafficgate.json @@ -12,12 +12,16 @@ "host": { "type": "string", "minLength": 1, - "description": "An ID which identifies the TrafficGate host" + "description": "An ID which identifies the TrafficGate host", + "pattern": "^[a-zA-Z0-9.-]+(:[0-9]+)?$" }, "customParams": { "type": "object", "description": "User-defined targeting key-value pairs." } }, - "required" : [ "placementId", "host" ] + "required": [ + "placementId", + "host" + ] } diff --git a/static/bidder-params/trustx.json b/static/bidder-params/trustx.json new file mode 100644 index 0000000000..7560642aae --- /dev/null +++ b/static/bidder-params/trustx.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "TRUSTX Adapter Params", + "description": "A schema which validates params accepted by the TRUSTX adapter", + "type": "object", + "properties": { + "uid": { + "type": "integer", + "description": "The ad slot id" + }, + "keywords": { + "type": "object", + "description": "Keywords" + } + } +} diff --git a/static/bidder-params/zeroclickfraud.json b/static/bidder-params/zeroclickfraud.json index 1c5e3c633b..5a306bad3e 100644 --- a/static/bidder-params/zeroclickfraud.json +++ b/static/bidder-params/zeroclickfraud.json @@ -2,18 +2,21 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "ZeroClickFraud Adapter Params", "description": "A schema which validates params accepted by the ZeroClickFraud adapter", - "type": "object", "properties": { - "sourceId": { - "type": "integer", - "minimum": 1, - "description": "Website Source Id" - }, - "host": { - "type": "string", - "description": "Network Host to request from" - } + "sourceId": { + "type": "integer", + "minimum": 1, + "description": "Website Source Id" + }, + "host": { + "type": "string", + "description": "Network Host to request from", + "pattern": "^[a-zA-Z0-9.-]+(:[0-9]+)?$" + } }, - "required": ["host", "sourceId"] + "required": [ + "host", + "sourceId" + ] } diff --git a/stored_requests/backends/db_fetcher/fetcher.go b/stored_requests/backends/db_fetcher/fetcher.go index fc16ca490b..13c5cb00b9 100644 --- a/stored_requests/backends/db_fetcher/fetcher.go +++ b/stored_requests/backends/db_fetcher/fetcher.go @@ -5,9 +5,9 @@ import ( "encoding/json" "github.com/lib/pq" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/stored_requests" - "github.com/prebid/prebid-server/v3/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests/backends/db_provider" ) func NewFetcher( diff --git a/stored_requests/backends/db_fetcher/fetcher_test.go b/stored_requests/backends/db_fetcher/fetcher_test.go index 6da09abf7b..1f4464bcb8 100644 --- a/stored_requests/backends/db_fetcher/fetcher_test.go +++ b/stored_requests/backends/db_fetcher/fetcher_test.go @@ -11,7 +11,7 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" - "github.com/prebid/prebid-server/v3/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v4/stored_requests/backends/db_provider" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/backends/db_provider/db_provider.go b/stored_requests/backends/db_provider/db_provider.go index be460bc351..cffdee24d9 100644 --- a/stored_requests/backends/db_provider/db_provider.go +++ b/stored_requests/backends/db_provider/db_provider.go @@ -4,8 +4,8 @@ import ( "context" "database/sql" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" ) type DbProvider interface { diff --git a/stored_requests/backends/db_provider/db_provider_mock.go b/stored_requests/backends/db_provider/db_provider_mock.go index 1b1c1ff601..37dd33f362 100644 --- a/stored_requests/backends/db_provider/db_provider_mock.go +++ b/stored_requests/backends/db_provider/db_provider_mock.go @@ -6,7 +6,7 @@ import ( "reflect" "github.com/DATA-DOG/go-sqlmock" - "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v4/config" ) func NewDbProviderMock() (*DbProviderMock, sqlmock.Sqlmock, error) { diff --git a/stored_requests/backends/db_provider/mysql_dbprovider.go b/stored_requests/backends/db_provider/mysql_dbprovider.go index bdcfacbae8..5071156f2f 100644 --- a/stored_requests/backends/db_provider/mysql_dbprovider.go +++ b/stored_requests/backends/db_provider/mysql_dbprovider.go @@ -15,7 +15,7 @@ import ( "strings" "github.com/go-sql-driver/mysql" - "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v4/config" ) const customTLSKey = "prebid-tls" diff --git a/stored_requests/backends/db_provider/mysql_dbprovider_test.go b/stored_requests/backends/db_provider/mysql_dbprovider_test.go index c12d7f5abc..474c36e4ef 100644 --- a/stored_requests/backends/db_provider/mysql_dbprovider_test.go +++ b/stored_requests/backends/db_provider/mysql_dbprovider_test.go @@ -6,7 +6,7 @@ import ( "runtime" "testing" - "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v4/config" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/backends/db_provider/postgres_dbprovider.go b/stored_requests/backends/db_provider/postgres_dbprovider.go index c94632a0f3..e58b336e48 100644 --- a/stored_requests/backends/db_provider/postgres_dbprovider.go +++ b/stored_requests/backends/db_provider/postgres_dbprovider.go @@ -10,7 +10,7 @@ import ( "strconv" "strings" - "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v4/config" ) type PostgresDbProvider struct { diff --git a/stored_requests/backends/db_provider/postgres_dbprovider_test.go b/stored_requests/backends/db_provider/postgres_dbprovider_test.go index 1be77d0d28..8fed6b87a3 100644 --- a/stored_requests/backends/db_provider/postgres_dbprovider_test.go +++ b/stored_requests/backends/db_provider/postgres_dbprovider_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v4/config" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/backends/empty_fetcher/fetcher.go b/stored_requests/backends/empty_fetcher/fetcher.go index 405903e533..79de895ab6 100644 --- a/stored_requests/backends/empty_fetcher/fetcher.go +++ b/stored_requests/backends/empty_fetcher/fetcher.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" - "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests" ) // EmptyFetcher is a nil-object which has no Stored Requests. diff --git a/stored_requests/backends/file_fetcher/fetcher.go b/stored_requests/backends/file_fetcher/fetcher.go index 6bb8bc1447..615135f2db 100644 --- a/stored_requests/backends/file_fetcher/fetcher.go +++ b/stored_requests/backends/file_fetcher/fetcher.go @@ -8,8 +8,8 @@ import ( "os" "strings" - "github.com/prebid/prebid-server/v3/stored_requests" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v5" ) diff --git a/stored_requests/backends/file_fetcher/fetcher_test.go b/stored_requests/backends/file_fetcher/fetcher_test.go index 735045dd9f..8ca38aa873 100644 --- a/stored_requests/backends/file_fetcher/fetcher_test.go +++ b/stored_requests/backends/file_fetcher/fetcher_test.go @@ -6,8 +6,8 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/v3/stored_requests" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/backends/http_fetcher/fetcher.go b/stored_requests/backends/http_fetcher/fetcher.go index c28d782e01..a0e6daba5a 100644 --- a/stored_requests/backends/http_fetcher/fetcher.go +++ b/stored_requests/backends/http_fetcher/fetcher.go @@ -9,9 +9,9 @@ import ( "net/url" "strings" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/stored_requests" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/util/jsonutil" "golang.org/x/net/context/ctxhttp" jsonpatch "gopkg.in/evanphx/json-patch.v5" ) @@ -119,7 +119,7 @@ func (fetcher *HttpFetcher) FetchAccounts(ctx context.Context, accountIDs []stri if len(accountIDs) == 0 { return nil, nil } - u := fetcher.EndpointURL + u := *fetcher.EndpointURL q := u.Query() if !fetcher.UseRfcCompliantBuilder { q.Set("account-ids", `["`+strings.Join(accountIDs, `","`)+`"]`) diff --git a/stored_requests/backends/http_fetcher/fetcher_test.go b/stored_requests/backends/http_fetcher/fetcher_test.go index 9d014eaf5a..e98032480c 100644 --- a/stored_requests/backends/http_fetcher/fetcher_test.go +++ b/stored_requests/backends/http_fetcher/fetcher_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -241,6 +241,64 @@ func TestFetchAccountRfcCompliant(t *testing.T) { assert.JSONEq(t, `{"disabled": true, "id":"acc-1"}`, string(account), "Unexpected account data fetching existing account") } +func TestFetchAccountsDoesNotAccumulateQueryParams(t *testing.T) { + var seen [][]string + + handler := func(w http.ResponseWriter, r *http.Request) { + got := richSplit(r.URL.Query().Get("account-ids")) + seen = append(seen, got) + + // Validate and respond using existing helper + newAccountHandler(t, got, false)(w, r) + } + + server := httptest.NewServer(http.HandlerFunc(handler)) + defer server.Close() + + fetcher := NewFetcher(server.Client(), server.URL, false) + + // first fetcher call + _, errs := fetcher.FetchAccounts(context.Background(), []string{"acc-1"}) + assert.Empty(t, errs) + + // second fetcher call with different account ID + _, errs = fetcher.FetchAccounts(context.Background(), []string{"acc-2"}) + assert.Empty(t, errs) + + assert.Equal(t, 2, len(seen)) + assert.Equal(t, []string{"acc-1"}, seen[0]) + assert.Equal(t, []string{"acc-2"}, seen[1]) +} + +func TestFetchAccountsDoesNotAccumulateQueryParamsRfcCompliant(t *testing.T) { + var seen [][]string + + handler := func(w http.ResponseWriter, r *http.Request) { + got := r.URL.Query()["account-id"] + seen = append(seen, got) + + // true flag for RFC compliant + newAccountHandler(t, got, true)(w, r) + } + + server := httptest.NewServer(http.HandlerFunc(handler)) + defer server.Close() + + fetcher := NewFetcher(server.Client(), server.URL, true) + + // first fetcher call + _, errs := fetcher.FetchAccounts(context.Background(), []string{"acc-1"}) + assert.Empty(t, errs) + + // second fetcher call with different account ID + _, errs = fetcher.FetchAccounts(context.Background(), []string{"acc-2"}) + assert.Empty(t, errs) + + assert.Equal(t, 2, len(seen)) + assert.Equal(t, []string{"acc-1"}, seen[0]) + assert.Equal(t, []string{"acc-2"}, seen[1]) +} + func TestFetchAccount(t *testing.T) { fetcher, close := newTestAccountFetcher(t, []string{"acc-1"}, false) defer close() diff --git a/stored_requests/caches/cachestest/reliable.go b/stored_requests/caches/cachestest/reliable.go index f4042e28c4..abea2dbff8 100644 --- a/stored_requests/caches/cachestest/reliable.go +++ b/stored_requests/caches/cachestest/reliable.go @@ -5,7 +5,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests" ) const ( diff --git a/stored_requests/caches/memory/cache.go b/stored_requests/caches/memory/cache.go index bae7a7ddcf..42d26e3e8e 100644 --- a/stored_requests/caches/memory/cache.go +++ b/stored_requests/caches/memory/cache.go @@ -6,8 +6,8 @@ import ( "sync" "github.com/coocood/freecache" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/stored_requests" ) // NewCache returns an in-memory Cache which evicts items if: diff --git a/stored_requests/caches/memory/cache_test.go b/stored_requests/caches/memory/cache_test.go index 91548e4693..26eab878e1 100644 --- a/stored_requests/caches/memory/cache_test.go +++ b/stored_requests/caches/memory/cache_test.go @@ -7,8 +7,8 @@ import ( "strconv" "testing" - "github.com/prebid/prebid-server/v3/stored_requests" - "github.com/prebid/prebid-server/v3/stored_requests/caches/cachestest" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests/caches/cachestest" ) func TestLRURobustness(t *testing.T) { diff --git a/stored_requests/caches/memory/maps.go b/stored_requests/caches/memory/maps.go index adf5b2a90d..501dc5ccbe 100644 --- a/stored_requests/caches/memory/maps.go +++ b/stored_requests/caches/memory/maps.go @@ -5,7 +5,7 @@ import ( "sync" "github.com/coocood/freecache" - "github.com/prebid/prebid-server/v3/logger" + "github.com/prebid/prebid-server/v4/logger" ) // This file contains an interface and some wrapper types for various types of "map-like" structures diff --git a/stored_requests/config/config.go b/stored_requests/config/config.go index 5ff729cdd3..87802589eb 100644 --- a/stored_requests/config/config.go +++ b/stored_requests/config/config.go @@ -6,22 +6,22 @@ import ( "time" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/metrics" - "github.com/prebid/prebid-server/v3/stored_requests" - "github.com/prebid/prebid-server/v3/stored_requests/backends/db_fetcher" - "github.com/prebid/prebid-server/v3/stored_requests/backends/db_provider" - "github.com/prebid/prebid-server/v3/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/v3/stored_requests/backends/file_fetcher" - "github.com/prebid/prebid-server/v3/stored_requests/backends/http_fetcher" - "github.com/prebid/prebid-server/v3/stored_requests/caches/memory" - "github.com/prebid/prebid-server/v3/stored_requests/caches/nil_cache" - "github.com/prebid/prebid-server/v3/stored_requests/events" - apiEvents "github.com/prebid/prebid-server/v3/stored_requests/events/api" - databaseEvents "github.com/prebid/prebid-server/v3/stored_requests/events/database" - httpEvents "github.com/prebid/prebid-server/v3/stored_requests/events/http" - "github.com/prebid/prebid-server/v3/util/task" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests/backends/db_fetcher" + "github.com/prebid/prebid-server/v4/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v4/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v4/stored_requests/backends/file_fetcher" + "github.com/prebid/prebid-server/v4/stored_requests/backends/http_fetcher" + "github.com/prebid/prebid-server/v4/stored_requests/caches/memory" + "github.com/prebid/prebid-server/v4/stored_requests/caches/nil_cache" + "github.com/prebid/prebid-server/v4/stored_requests/events" + apiEvents "github.com/prebid/prebid-server/v4/stored_requests/events/api" + databaseEvents "github.com/prebid/prebid-server/v4/stored_requests/events/database" + httpEvents "github.com/prebid/prebid-server/v4/stored_requests/events/http" + "github.com/prebid/prebid-server/v4/util/task" ) // CreateStoredRequests returns three things: diff --git a/stored_requests/config/config_test.go b/stored_requests/config/config_test.go index 87b396c926..913f8c3959 100644 --- a/stored_requests/config/config_test.go +++ b/stored_requests/config/config_test.go @@ -13,14 +13,14 @@ import ( sqlmock "github.com/DATA-DOG/go-sqlmock" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/metrics" - "github.com/prebid/prebid-server/v3/stored_requests" - "github.com/prebid/prebid-server/v3/stored_requests/backends/db_provider" - "github.com/prebid/prebid-server/v3/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/v3/stored_requests/backends/http_fetcher" - "github.com/prebid/prebid-server/v3/stored_requests/events" - httpEvents "github.com/prebid/prebid-server/v3/stored_requests/events/http" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v4/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v4/stored_requests/backends/http_fetcher" + "github.com/prebid/prebid-server/v4/stored_requests/events" + httpEvents "github.com/prebid/prebid-server/v4/stored_requests/events/http" "github.com/stretchr/testify/mock" ) diff --git a/stored_requests/events/api/api.go b/stored_requests/events/api/api.go index c9f87e0ae7..652399717e 100644 --- a/stored_requests/events/api/api.go +++ b/stored_requests/events/api/api.go @@ -5,8 +5,8 @@ import ( "net/http" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v3/stored_requests/events" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/stored_requests/events" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type eventsAPI struct { diff --git a/stored_requests/events/api/api_test.go b/stored_requests/events/api/api_test.go index c5d67a9b86..87a516f792 100644 --- a/stored_requests/events/api/api_test.go +++ b/stored_requests/events/api/api_test.go @@ -9,9 +9,9 @@ import ( "strings" "testing" - "github.com/prebid/prebid-server/v3/stored_requests" - "github.com/prebid/prebid-server/v3/stored_requests/caches/memory" - "github.com/prebid/prebid-server/v3/stored_requests/events" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests/caches/memory" + "github.com/prebid/prebid-server/v4/stored_requests/events" ) func TestGoodRequests(t *testing.T) { diff --git a/stored_requests/events/database/database.go b/stored_requests/events/database/database.go index 1ab768c97c..c29bc4a855 100644 --- a/stored_requests/events/database/database.go +++ b/stored_requests/events/database/database.go @@ -8,12 +8,12 @@ import ( "net" "time" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/metrics" - "github.com/prebid/prebid-server/v3/stored_requests/backends/db_provider" - "github.com/prebid/prebid-server/v3/stored_requests/events" - "github.com/prebid/prebid-server/v3/util/timeutil" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v4/stored_requests/events" + "github.com/prebid/prebid-server/v4/util/timeutil" ) func bytesNull() []byte { diff --git a/stored_requests/events/database/database_test.go b/stored_requests/events/database/database_test.go index ffe02851ca..0c09f376dd 100644 --- a/stored_requests/events/database/database_test.go +++ b/stored_requests/events/database/database_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/metrics" - "github.com/prebid/prebid-server/v3/stored_requests/backends/db_provider" - "github.com/prebid/prebid-server/v3/stored_requests/events" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v4/stored_requests/events" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/stored_requests/events/events.go b/stored_requests/events/events.go index e96692826b..f0d30878c9 100644 --- a/stored_requests/events/events.go +++ b/stored_requests/events/events.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" - "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests" ) // Save represents a bulk save diff --git a/stored_requests/events/events_test.go b/stored_requests/events/events_test.go index 4520a33255..9f977c8e9f 100644 --- a/stored_requests/events/events_test.go +++ b/stored_requests/events/events_test.go @@ -7,8 +7,8 @@ import ( "reflect" "testing" - "github.com/prebid/prebid-server/v3/stored_requests" - "github.com/prebid/prebid-server/v3/stored_requests/caches/memory" + "github.com/prebid/prebid-server/v4/stored_requests" + "github.com/prebid/prebid-server/v4/stored_requests/caches/memory" ) func TestListen(t *testing.T) { diff --git a/stored_requests/events/http/http.go b/stored_requests/events/http/http.go index f987afb658..2765cb4aae 100644 --- a/stored_requests/events/http/http.go +++ b/stored_requests/events/http/http.go @@ -10,9 +10,9 @@ import ( "time" "github.com/buger/jsonparser" - "github.com/prebid/prebid-server/v3/logger" - "github.com/prebid/prebid-server/v3/stored_requests/events" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/logger" + "github.com/prebid/prebid-server/v4/stored_requests/events" + "github.com/prebid/prebid-server/v4/util/jsonutil" "golang.org/x/net/context/ctxhttp" ) diff --git a/stored_requests/events/http/http_test.go b/stored_requests/events/http/http_test.go index 90fd61371c..9254484688 100644 --- a/stored_requests/events/http/http_test.go +++ b/stored_requests/events/http/http_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/fetcher.go b/stored_requests/fetcher.go index 343e1f82d5..2abfb33052 100644 --- a/stored_requests/fetcher.go +++ b/stored_requests/fetcher.go @@ -5,7 +5,7 @@ import ( "encoding/json" "fmt" - "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v4/metrics" ) // Fetcher knows how to fetch Stored Request data by id. diff --git a/stored_requests/fetcher_test.go b/stored_requests/fetcher_test.go index c97340cbdb..4481600e9d 100644 --- a/stored_requests/fetcher_test.go +++ b/stored_requests/fetcher_test.go @@ -6,8 +6,8 @@ import ( "errors" "testing" - "github.com/prebid/prebid-server/v3/metrics" - "github.com/prebid/prebid-server/v3/stored_requests/caches/nil_cache" + "github.com/prebid/prebid-server/v4/metrics" + "github.com/prebid/prebid-server/v4/stored_requests/caches/nil_cache" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/stored_responses/stored_responses.go b/stored_responses/stored_responses.go index 6c8d4ae5f6..a7a3abc4f3 100644 --- a/stored_responses/stored_responses.go +++ b/stored_responses/stored_responses.go @@ -7,8 +7,8 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/stored_requests" ) type ImpsWithAuctionResponseIDs map[string]string diff --git a/stored_responses/stored_responses_test.go b/stored_responses/stored_responses_test.go index 0dcd5e9a6d..09bf429a9f 100644 --- a/stored_responses/stored_responses_test.go +++ b/stored_responses/stored_responses_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/usersync/bidderchooser.go b/usersync/bidderchooser.go index 1b01e5116e..046d5c3a19 100644 --- a/usersync/bidderchooser.go +++ b/usersync/bidderchooser.go @@ -13,7 +13,7 @@ type standardBidderChooser struct { func (c standardBidderChooser) choose(requested, available []string, cooperative Cooperative) []string { if cooperative.Enabled { - return c.chooseCooperative(requested, available, cooperative.PriorityGroups) + return c.chooseCooperative(requested, available, cooperative) } if len(requested) == 0 { @@ -23,7 +23,7 @@ func (c standardBidderChooser) choose(requested, available []string, cooperative return c.shuffledCopy(requested) } -func (c standardBidderChooser) chooseCooperative(requested, available []string, priorityGroups [][]string) []string { +func (c standardBidderChooser) chooseCooperative(requested, available []string, cooperative Cooperative) []string { // allocate enough memory for the slice to try to avoid re-allocation. the 50% overhead is a guess // at a satisfactory value. since all available bidders are included in the slice, along with // requested and prioritized bidders, expect there to be be many duplicates. the duplicate are @@ -35,12 +35,14 @@ func (c standardBidderChooser) chooseCooperative(requested, available []string, bidders = c.shuffledAppend(bidders, requested) // priority groups - for _, group := range priorityGroups { + for _, group := range cooperative.PriorityGroups { bidders = c.shuffledAppend(bidders, group) } // available - bidders = c.shuffledAppend(bidders, available) + if !cooperative.PriorityGroupsOnly { + bidders = c.shuffledAppend(bidders, available) + } return bidders } diff --git a/usersync/bidderchooser_test.go b/usersync/bidderchooser_test.go index fe7d296f1f..cdf007aa3c 100644 --- a/usersync/bidderchooser_test.go +++ b/usersync/bidderchooser_test.go @@ -62,6 +62,12 @@ func TestBidderChooserChoose(t *testing.T) { givenCooperative: Cooperative{Enabled: true, PriorityGroups: [][]string{{"pr1A", "pr1B"}, {"pr2A", "pr2B"}}}, expected: []string{"r2", "r1", "pr1B", "pr1A", "pr2B", "pr2A", "a2", "a1"}, }, + { + description: "Coop - PriorityGroupsOnly", + givenRequested: []string{"r1", "r2"}, + givenCooperative: Cooperative{Enabled: true, PriorityGroups: [][]string{{"pr1A", "pr1B"}}, PriorityGroupsOnly: true}, + expected: []string{"r2", "r1", "pr1B", "pr1A"}, + }, } for _, test := range testCases { @@ -76,55 +82,64 @@ func TestBidderChooserCooperative(t *testing.T) { shuffler := reverseShuffler{} available := []string{"a1", "a2"} - testCases := []struct { - description string - givenRequested []string - givenPriorityGroups [][]string - expected []string + testCases := map[string]struct { + givenRequested []string + givenCoop Cooperative + expected []string }{ - { - description: "Nil", - givenRequested: nil, - givenPriorityGroups: nil, - expected: []string{"a2", "a1"}, + "nil": { + givenRequested: nil, + givenCoop: Cooperative{Enabled: true}, + expected: []string{"a2", "a1"}, }, - { - description: "Empty", - givenRequested: []string{}, - givenPriorityGroups: [][]string{}, - expected: []string{"a2", "a1"}, + "empty": { + givenRequested: []string{}, + givenCoop: Cooperative{Enabled: true, PriorityGroups: [][]string{}}, + expected: []string{"a2", "a1"}, }, - { - description: "Requested", - givenRequested: []string{"r1", "r2"}, - givenPriorityGroups: nil, - expected: []string{"r2", "r1", "a2", "a1"}, + "requested": { + givenRequested: []string{"r1", "r2"}, + givenCoop: Cooperative{Enabled: true}, + expected: []string{"r2", "r1", "a2", "a1"}, }, - { - description: "Priority Groups - One", - givenRequested: nil, - givenPriorityGroups: [][]string{{"pr1A", "pr1B"}}, - expected: []string{"pr1B", "pr1A", "a2", "a1"}, + "priority_groups_one": { + givenRequested: nil, + givenCoop: Cooperative{Enabled: true, PriorityGroups: [][]string{{"pr1A", "pr1B"}}}, + expected: []string{"pr1B", "pr1A", "a2", "a1"}, }, - { - description: "Priority Groups - Many", - givenRequested: nil, - givenPriorityGroups: [][]string{{"pr1A", "pr1B"}, {"pr2A", "pr2B"}}, - expected: []string{"pr1B", "pr1A", "pr2B", "pr2A", "a2", "a1"}, + "priority_groups_many": { + givenRequested: nil, + givenCoop: Cooperative{Enabled: true, PriorityGroups: [][]string{{"pr1A", "pr1B"}, {"pr2A", "pr2B"}}}, + expected: []string{"pr1B", "pr1A", "pr2B", "pr2A", "a2", "a1"}, }, - { - description: "Requested + Priority Groups", - givenRequested: []string{"r1", "r2"}, - givenPriorityGroups: [][]string{{"pr1A", "pr1B"}, {"pr2A", "pr2B"}}, - expected: []string{"r2", "r1", "pr1B", "pr1A", "pr2B", "pr2A", "a2", "a1"}, + "requested_and_priority_groups": { + givenRequested: []string{"r1", "r2"}, + givenCoop: Cooperative{Enabled: true, PriorityGroups: [][]string{{"pr1A", "pr1B"}, {"pr2A", "pr2B"}}}, + expected: []string{"r2", "r1", "pr1B", "pr1A", "pr2B", "pr2A", "a2", "a1"}, + }, + "priority_groups_only_no_remaining": { + givenRequested: []string{"r1", "r2"}, + givenCoop: Cooperative{Enabled: true, PriorityGroups: [][]string{{"pr1A", "pr1B"}}, PriorityGroupsOnly: true}, + expected: []string{"r2", "r1", "pr1B", "pr1A"}, + }, + "priority_groups_only_no_requested": { + givenRequested: nil, + givenCoop: Cooperative{Enabled: true, PriorityGroups: [][]string{{"pr1A", "pr1B"}, {"pr2A", "pr2B"}}, PriorityGroupsOnly: true}, + expected: []string{"pr1B", "pr1A", "pr2B", "pr2A"}, + }, + "priority_groups_only_empty_groups": { + givenRequested: []string{"r1", "r2"}, + givenCoop: Cooperative{Enabled: true, PriorityGroups: [][]string{}, PriorityGroupsOnly: true}, + expected: []string{"r2", "r1"}, }, } - for _, test := range testCases { - chooser := standardBidderChooser{shuffler: shuffler} - result := chooser.chooseCooperative(test.givenRequested, available, test.givenPriorityGroups) - - assert.Equal(t, test.expected, result, test.description) + for name, test := range testCases { + t.Run(name, func(t *testing.T) { + chooser := standardBidderChooser{shuffler: shuffler} + result := chooser.chooseCooperative(test.givenRequested, available, test.givenCoop) + assert.Equal(t, test.expected, result) + }) } } diff --git a/usersync/bidderfilter.go b/usersync/bidderfilter.go index 2e4df476f2..47a7fca646 100644 --- a/usersync/bidderfilter.go +++ b/usersync/bidderfilter.go @@ -64,3 +64,21 @@ func (f UniformBidderFilter) Allowed(bidder string) bool { func NewUniformBidderFilter(mode BidderFilterMode) BidderFilter { return UniformBidderFilter{mode: mode} } + +type CompositeFilter struct { + RequestFilter BidderFilter + AccountFilter BidderFilter +} + +func (f CompositeFilter) Allowed(bidder string) bool { + if f.RequestFilter == nil && f.AccountFilter == nil { + return true + } + if f.RequestFilter == nil { + return f.AccountFilter.Allowed(bidder) + } + if f.AccountFilter == nil { + return f.RequestFilter.Allowed(bidder) + } + return f.RequestFilter.Allowed(bidder) && f.AccountFilter.Allowed(bidder) +} diff --git a/usersync/chooser.go b/usersync/chooser.go index 31a14a4d43..88913a76cc 100644 --- a/usersync/chooser.go +++ b/usersync/chooser.go @@ -3,8 +3,8 @@ package usersync import ( "strings" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) // Chooser determines which syncers are eligible for a given request. @@ -46,8 +46,9 @@ type Request struct { // Cooperative specifies the settings for cooperative syncing for a given request, where bidders // other than those used by the publisher are considered for syncing. type Cooperative struct { - Enabled bool - PriorityGroups [][]string + Enabled bool + PriorityGroups [][]string + PriorityGroupsOnly bool } // Result specifies which bidders were included in the evaluation and which syncers were chosen. diff --git a/usersync/chooser_test.go b/usersync/chooser_test.go index 2674330c30..569dd0ea11 100644 --- a/usersync/chooser_test.go +++ b/usersync/chooser_test.go @@ -4,13 +4,13 @@ import ( "testing" "time" - "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/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v4/macros" ) func TestNewChooser(t *testing.T) { diff --git a/usersync/cookie.go b/usersync/cookie.go index dce5b02095..deefccced1 100644 --- a/usersync/cookie.go +++ b/usersync/cookie.go @@ -5,9 +5,9 @@ import ( "net/http" "time" - "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/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) const uidCookieName = "uids" @@ -61,7 +61,7 @@ func (cookie *Cookie) PrepareCookieForWrite(cfg *config.HostCookie, encoder Enco for len(cookie.uids) > 0 { encodedCookie, err := encoder.Encode(cookie) if err != nil { - return encodedCookie, nil + return encodedCookie, err } // Convert to HTTP Cookie to Get Size diff --git a/usersync/cookie_test.go b/usersync/cookie_test.go index 79193d92a6..07db4a8763 100644 --- a/usersync/cookie_test.go +++ b/usersync/cookie_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -533,6 +533,23 @@ func TestPrepareCookieForWrite(t *testing.T) { } } +type failingEncoder struct{} + +func (failingEncoder) Encode(*Cookie) (string, error) { + return "", errors.New("encode failed") +} + +func TestPrepareCookieForWriteEncoderError(t *testing.T) { + cookie := &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": newTempId("UID", 1), + }, + } + + _, err := cookie.PrepareCookieForWrite(&config.HostCookie{}, failingEncoder{}, nil) + assert.Error(t, err) +} + func TestSyncHostCookie(t *testing.T) { testCases := []struct { name string diff --git a/usersync/decoder.go b/usersync/decoder.go index d77c8d426b..30a0c5ceb6 100644 --- a/usersync/decoder.go +++ b/usersync/decoder.go @@ -3,7 +3,7 @@ package usersync import ( "encoding/base64" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type Decoder interface { diff --git a/usersync/encoder.go b/usersync/encoder.go index 6a7db1fe51..14c71ed3b4 100644 --- a/usersync/encoder.go +++ b/usersync/encoder.go @@ -3,7 +3,7 @@ package usersync import ( "encoding/base64" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) type Encoder interface { diff --git a/usersync/syncer.go b/usersync/syncer.go index b2fec61610..10ec089abb 100644 --- a/usersync/syncer.go +++ b/usersync/syncer.go @@ -9,8 +9,8 @@ import ( "text/template" validator "github.com/asaskevich/govalidator" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/macros" ) var ( @@ -39,9 +39,8 @@ type Syncer interface { // Sync represents a user sync to be performed by the user's device. type Sync struct { - URL string - Type SyncType - SupportCORS bool + URL string + Type SyncType } type standardSyncer struct { @@ -49,7 +48,6 @@ type standardSyncer struct { defaultSyncType SyncType iframe *template.Template redirect *template.Template - supportCORS bool formatOverride string } @@ -67,7 +65,6 @@ func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer, bidder st syncer := standardSyncer{ key: syncerConfig.Key, defaultSyncType: resolveDefaultSyncType(syncerConfig), - supportCORS: syncerConfig.SupportCORS != nil && *syncerConfig.SupportCORS, formatOverride: syncerConfig.FormatOverride, } @@ -237,9 +234,8 @@ func (s standardSyncer) GetSync(syncTypes []SyncType, userSyncMacros macros.User } sync := Sync{ - URL: url, - Type: syncType, - SupportCORS: s.supportCORS, + URL: url, + Type: syncType, } return sync, nil } diff --git a/usersync/syncer_test.go b/usersync/syncer_test.go index 020fb26df6..827dee4628 100644 --- a/usersync/syncer_test.go +++ b/usersync/syncer_test.go @@ -4,14 +4,13 @@ import ( "testing" "text/template" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/macros" "github.com/stretchr/testify/assert" ) func TestNewSyncer(t *testing.T) { var ( - supportCORS = true hostConfig = config.UserSync{ExternalURL: "http://host.com", RedirectURL: "{{.ExternalURL}}/host"} macroValues = macros.UserSyncPrivacy{GDPR: "A", GDPRConsent: "B", USPrivacy: "C"} iframeConfig = &config.SyncerEndpoint{URL: "https://bidder.com/iframe?redirect={{.RedirectURL}}"} @@ -107,7 +106,6 @@ func TestNewSyncer(t *testing.T) { for _, test := range testCases { syncerConfig := config.Syncer{ Key: test.givenKey, - SupportCORS: &supportCORS, IFrame: test.givenIFrameConfig, Redirect: test.givenRedirectConfig, ExternalURL: test.givenExternalURL, @@ -120,7 +118,6 @@ func TestNewSyncer(t *testing.T) { if assert.IsType(t, standardSyncer{}, result, test.description+":result_type") { result := result.(standardSyncer) assert.Equal(t, test.givenKey, result.key, test.description+":key") - assert.Equal(t, supportCORS, result.supportCORS, test.description+":cors") assert.Equal(t, test.expectedDefault, result.defaultSyncType, test.description+":default_sync") if test.expectedIFrame == "" { @@ -682,14 +679,14 @@ func TestSyncerGetSync(t *testing.T) { givenSyncer: standardSyncer{iframe: iframeTemplate, redirect: redirectTemplate}, givenSyncTypes: []SyncType{SyncTypeIFrame}, givenMacros: macros.UserSyncPrivacy{GDPR: "A", GDPRConsent: "B", USPrivacy: "C"}, - expectedSync: Sync{URL: "iframe,gdpr:A,gdprconsent:B,ccpa:C", Type: SyncTypeIFrame, SupportCORS: false}, + expectedSync: Sync{URL: "iframe,gdpr:A,gdprconsent:B,ccpa:C", Type: SyncTypeIFrame}, }, { description: "Redirect", givenSyncer: standardSyncer{iframe: iframeTemplate, redirect: redirectTemplate}, givenSyncTypes: []SyncType{SyncTypeRedirect}, givenMacros: macros.UserSyncPrivacy{GDPR: "A", GDPRConsent: "B", USPrivacy: "C"}, - expectedSync: Sync{URL: "redirect,gdpr:A,gdprconsent:B,ccpa:C", Type: SyncTypeRedirect, SupportCORS: false}, + expectedSync: Sync{URL: "redirect,gdpr:A,gdprconsent:B,ccpa:C", Type: SyncTypeRedirect}, }, { description: "Macro Error", diff --git a/usersync/syncersbuilder.go b/usersync/syncersbuilder.go index 2868a1da7d..b8a11e66dd 100644 --- a/usersync/syncersbuilder.go +++ b/usersync/syncersbuilder.go @@ -5,7 +5,7 @@ import ( "sort" "strings" - "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v4/config" ) type namedSyncerConfig struct { diff --git a/usersync/syncersbuilder_test.go b/usersync/syncersbuilder_test.go index a08df08172..b32b741b7c 100644 --- a/usersync/syncersbuilder_test.go +++ b/usersync/syncersbuilder_test.go @@ -4,8 +4,8 @@ import ( "errors" "testing" - "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v4/config" + "github.com/prebid/prebid-server/v4/macros" "github.com/stretchr/testify/assert" ) @@ -192,7 +192,6 @@ func TestShouldCreateSyncer(t *testing.T) { var ( anySupports = []string{"iframe"} anyEndpoint = &config.SyncerEndpoint{} - anyCORS = true ) testCases := []struct { @@ -212,7 +211,7 @@ func TestShouldCreateSyncer(t *testing.T) { }, { description: "Enabled, Syncer - Fully Loaded", - given: config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Key: "anyKey", Supports: anySupports, IFrame: anyEndpoint, Redirect: anyEndpoint, SupportCORS: &anyCORS}}, + given: config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Key: "anyKey", Supports: anySupports, IFrame: anyEndpoint, Redirect: anyEndpoint}}, expected: true, }, { @@ -235,11 +234,6 @@ func TestShouldCreateSyncer(t *testing.T) { given: config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Redirect: anyEndpoint}}, expected: true, }, - { - description: "Enabled, Syncer - Only SupportCORS", - given: config.BidderInfo{Disabled: false, Syncer: &config.Syncer{SupportCORS: &anyCORS}}, - expected: true, - }, { description: "Disabled, No Syncer", given: config.BidderInfo{Disabled: true, Syncer: nil}, @@ -252,7 +246,7 @@ func TestShouldCreateSyncer(t *testing.T) { }, { description: "Disabled, Syncer - Fully Loaded", - given: config.BidderInfo{Disabled: true, Syncer: &config.Syncer{Key: "anyKey", Supports: anySupports, IFrame: anyEndpoint, Redirect: anyEndpoint, SupportCORS: &anyCORS}}, + given: config.BidderInfo{Disabled: true, Syncer: &config.Syncer{Key: "anyKey", Supports: anySupports, IFrame: anyEndpoint, Redirect: anyEndpoint}}, expected: false, }, { @@ -275,11 +269,6 @@ func TestShouldCreateSyncer(t *testing.T) { given: config.BidderInfo{Disabled: true, Syncer: &config.Syncer{Redirect: anyEndpoint}}, expected: false, }, - { - description: "Disabled, Syncer - Only SupportCORS", - given: config.BidderInfo{Disabled: true, Syncer: &config.Syncer{SupportCORS: &anyCORS}}, - expected: false, - }, { description: "WhiteLabelOnly, No Syncer", given: config.BidderInfo{WhiteLabelOnly: true, Syncer: nil}, @@ -292,7 +281,7 @@ func TestShouldCreateSyncer(t *testing.T) { }, { description: "WhiteLabelOnly, Syncer - Fully Loaded", - given: config.BidderInfo{WhiteLabelOnly: true, Syncer: &config.Syncer{Key: "anyKey", Supports: anySupports, IFrame: anyEndpoint, Redirect: anyEndpoint, SupportCORS: &anyCORS}}, + given: config.BidderInfo{WhiteLabelOnly: true, Syncer: &config.Syncer{Key: "anyKey", Supports: anySupports, IFrame: anyEndpoint, Redirect: anyEndpoint}}, expected: false, }, } diff --git a/util/httputil/httputil.go b/util/httputil/httputil.go index dd09cdadf4..3cf80b8c77 100644 --- a/util/httputil/httputil.go +++ b/util/httputil/httputil.go @@ -5,7 +5,7 @@ import ( "net/http" "strings" - "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v4/util/iputil" ) var ( diff --git a/util/httputil/httputil_test.go b/util/httputil/httputil_test.go index 2b2f52e5c5..f8b9ba5440 100644 --- a/util/httputil/httputil_test.go +++ b/util/httputil/httputil_test.go @@ -5,7 +5,7 @@ import ( "net/http" "testing" - "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v4/util/iputil" "github.com/stretchr/testify/assert" ) diff --git a/util/jsonutil/forcestring.go b/util/jsonutil/forcestring.go index 64ce2a6795..e16d85683d 100644 --- a/util/jsonutil/forcestring.go +++ b/util/jsonutil/forcestring.go @@ -3,7 +3,7 @@ package jsonutil import ( "errors" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/tidwall/gjson" ) diff --git a/util/jsonutil/forcestring_test.go b/util/jsonutil/forcestring_test.go index 60f87fafa4..3fc1cb6803 100644 --- a/util/jsonutil/forcestring_test.go +++ b/util/jsonutil/forcestring_test.go @@ -3,7 +3,7 @@ package jsonutil import ( "testing" - "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v4/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/util/jsonutil/jsonutil.go b/util/jsonutil/jsonutil.go index 2598044ff7..da9027c1df 100644 --- a/util/jsonutil/jsonutil.go +++ b/util/jsonutil/jsonutil.go @@ -9,7 +9,7 @@ import ( jsoniter "github.com/json-iterator/go" "github.com/modern-go/reflect2" - "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v4/errortypes" ) const ( diff --git a/util/jsonutil/merge.go b/util/jsonutil/merge.go index 6dff8afca6..9e530a5464 100644 --- a/util/jsonutil/merge.go +++ b/util/jsonutil/merge.go @@ -10,7 +10,7 @@ import ( "github.com/modern-go/reflect2" jsonpatch "gopkg.in/evanphx/json-patch.v5" - "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v4/errortypes" ) // jsonConfigMergeClone uses the same configuration as the `ConfigCompatibleWithStandardLibrary` profile diff --git a/util/task/ticker_task_test.go b/util/task/ticker_task_test.go index b1acb35ffa..774febd6c8 100644 --- a/util/task/ticker_task_test.go +++ b/util/task/ticker_task_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v3/util/task" + "github.com/prebid/prebid-server/v4/util/task" "github.com/stretchr/testify/assert" ) diff --git a/util/urlutil/security.go b/util/urlutil/security.go new file mode 100644 index 0000000000..51b9b5a6b9 --- /dev/null +++ b/util/urlutil/security.go @@ -0,0 +1,12 @@ +package urlutil + +import "regexp" + +var safeHostPattern = regexp.MustCompile(`^[a-zA-Z0-9.-]+(:[0-9]+)?$`) + +// IsSafeHost returns true for bare hostnames with an optional port. +// It intentionally rejects URL control characters such as '/', '?', '#', and '@' +// so user-supplied host values cannot rewrite the outbound request URL. +func IsSafeHost(host string) bool { + return safeHostPattern.MatchString(host) +} diff --git a/util/urlutil/security_test.go b/util/urlutil/security_test.go new file mode 100644 index 0000000000..d974f7cfa2 --- /dev/null +++ b/util/urlutil/security_test.go @@ -0,0 +1,68 @@ +package urlutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIsSafeHost(t *testing.T) { + testCases := []struct { + name string + host string + want bool + }{ + { + name: "hostname", + host: "example.com", + want: true, + }, + { + name: "subdomain", + host: "api-us", + want: true, + }, + { + name: "hostname with port", + host: "example.com:8080", + want: true, + }, + { + name: "empty", + host: "", + want: false, + }, + { + name: "path injection", + host: "127.0.0.1:6060/debug/pprof", + want: false, + }, + { + name: "fragment injection", + host: "127.0.0.1:6060#", + want: false, + }, + { + name: "query injection", + host: "example.com?x=1", + want: false, + }, + { + name: "userinfo injection", + host: "example.com@127.0.0.1", + want: false, + }, + { + name: "scheme injection", + host: "http://127.0.0.1", + want: false, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + result := IsSafeHost(test.host) + assert.Equal(t, test.want, result) + }) + } +} diff --git a/version/xprebidheader.go b/version/xprebidheader.go index 7e31aa4b11..056246474c 100644 --- a/version/xprebidheader.go +++ b/version/xprebidheader.go @@ -5,7 +5,7 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v4/openrtb_ext" ) const xPrebidHeaderVersionPrefix = "pbs-go" diff --git a/version/xprebidheader_test.go b/version/xprebidheader_test.go index 15a73fe98f..0e74584c7e 100644 --- a/version/xprebidheader_test.go +++ b/version/xprebidheader_test.go @@ -6,8 +6,8 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v4/openrtb_ext" + "github.com/prebid/prebid-server/v4/util/jsonutil" ) func TestBuildXPrebidHeader(t *testing.T) {