From 810c6b45ac5eb86c2399a5717e605b4c8a020bab Mon Sep 17 00:00:00 2001 From: markiian Date: Mon, 16 Dec 2024 16:34:26 +0200 Subject: [PATCH 1/7] Add functional tests for Transition PAAPI parameters to updated IAB conventions. --- .../model/config/AccountAuctionConfig.groovy | 2 + .../request/auction/AuctionEnvironment.groovy | 21 + .../model/request/auction/ImpExt.groovy | 4 +- .../InterestGroupAuctionSupport.groovy | 11 + .../model/request/auction/PaaFormant.groovy | 13 + .../model/request/auction/Prebid.groovy | 1 + .../response/auction/BidResponseExt.groovy | 3 + .../auction/InterestGroupAuctionBuyer.groovy | 17 + .../InterestGroupAuctionBuyerExt.groovy | 10 + .../auction/InterestGroupAuctionIntent.groovy | 18 + .../InterestGroupAuctionIntentExt.groovy | 11 + .../auction/InterestGroupAuctionSeller.groovy | 14 + .../InterestGroupAuctionSellerExt.groovy | 10 + .../response/auction/OpenxBidResponse.groovy | 1 - .../functional/tests/BidderParamsSpec.groovy | 74 ++- .../tests/bidder/openx/OpenxSpec.groovy | 493 +++++++++++++++++- 16 files changed, 695 insertions(+), 8 deletions(-) create mode 100644 src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/request/auction/InterestGroupAuctionSupport.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormant.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyer.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyerExt.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntent.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntentExt.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSeller.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSellerExt.groovy diff --git a/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy b/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy index 4e423c03312..2233c6b8fe0 100644 --- a/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming import groovy.transform.ToString import org.prebid.server.functional.model.bidder.BidderName import org.prebid.server.functional.model.request.auction.BidAdjustment +import org.prebid.server.functional.model.request.auction.PaaFormant import org.prebid.server.functional.model.request.auction.Targeting import org.prebid.server.functional.model.response.auction.MediaType @@ -23,6 +24,7 @@ class AccountAuctionConfig { AccountEventsConfig events AccountPriceFloorsConfig priceFloors Targeting targeting + PaaFormant paaformat @JsonProperty("preferredmediatype") Map preferredMediaType @JsonProperty("privacysandbox") diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy new file mode 100644 index 00000000000..6e779e547cd --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy @@ -0,0 +1,21 @@ +package org.prebid.server.functional.model.request.auction + +import com.fasterxml.jackson.annotation.JsonValue +import org.prebid.server.functional.util.PBSUtils + +enum AuctionEnvironment { + + NOT_SUPPORTED(0), + DEVICE_ORCHESTRATED(1), + SERVER_ORCHESTRATED(3), + UNKNOWN(PBSUtils.getRandomNumberWithExclusion([NOT_SUPPORTED.value, + DEVICE_ORCHESTRATED.value, + SERVER_ORCHESTRATED.value])), + + @JsonValue + private int value + + AuctionEnvironment(Integer value) { + this.value = value + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy index e817a4540a0..7bf15ce0d34 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy @@ -23,10 +23,12 @@ class ImpExt { String tid String gpid String sid - Integer ae + AuctionEnvironment ae String all String skadn String general + @JsonProperty("igs") + InterestGroupAuctionSupport interestGroupAuctionSupport AnyUnsupportedBidder anyUnsupportedBidder static ImpExt getDefaultImpExt() { diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/InterestGroupAuctionSupport.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/InterestGroupAuctionSupport.groovy new file mode 100644 index 00000000000..31d3628587d --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/InterestGroupAuctionSupport.groovy @@ -0,0 +1,11 @@ +package org.prebid.server.functional.model.request.auction + +import com.fasterxml.jackson.annotation.JsonProperty +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class InterestGroupAuctionSupport { + + @JsonProperty("ae") + AuctionEnvironment auctionEnvironment +} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormant.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormant.groovy new file mode 100644 index 00000000000..5d95dc9db91 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormant.groovy @@ -0,0 +1,13 @@ +package org.prebid.server.functional.model.request.auction + +import com.fasterxml.jackson.annotation.JsonValue + +enum PaaFormant { + + ORIGINAL, IAB + + @JsonValue + String getValue() { + name().toLowerCase() + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy index ba89f5680fa..e2f560ccba8 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy @@ -40,6 +40,7 @@ class Prebid { PrebidModulesConfig modules PrebidAnalytics analytics StoredAuctionResponse storedAuctionResponse + PaaFormant paaFormat static class Channel { diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponseExt.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponseExt.groovy index 3ccb3384e89..d1d282d663a 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponseExt.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponseExt.groovy @@ -1,5 +1,6 @@ package org.prebid.server.functional.model.response.auction +import com.fasterxml.jackson.annotation.JsonProperty import groovy.transform.ToString import org.prebid.server.functional.model.response.BidderError import org.prebid.server.functional.model.response.Debug @@ -15,4 +16,6 @@ class BidResponseExt { Map usersync BidResponsePrebid prebid Map> warnings + @JsonProperty("igi") + List interestGroupAuctionIntent } diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyer.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyer.groovy new file mode 100644 index 00000000000..b8d1bf80d38 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyer.groovy @@ -0,0 +1,17 @@ +package org.prebid.server.functional.model.response.auction + +import com.fasterxml.jackson.databind.PropertyNamingStrategies +import com.fasterxml.jackson.databind.annotation.JsonNaming +import groovy.transform.ToString +import org.prebid.server.functional.model.Currency + +@ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) +class InterestGroupAuctionBuyer { + + String origin + BigDecimal maxBid + Currency cur + Map pbs + InterestGroupAuctionBuyerExt ext +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyerExt.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyerExt.groovy new file mode 100644 index 00000000000..4404491246c --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyerExt.groovy @@ -0,0 +1,10 @@ +package org.prebid.server.functional.model.response.auction + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class InterestGroupAuctionBuyerExt { + + String bidder + String adapter +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntent.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntent.groovy new file mode 100644 index 00000000000..29ff15d4eeb --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntent.groovy @@ -0,0 +1,18 @@ +package org.prebid.server.functional.model.response.auction + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.databind.PropertyNamingStrategies +import com.fasterxml.jackson.databind.annotation.JsonNaming +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) +class InterestGroupAuctionIntent { + + String impId + @JsonProperty("igb") + List interestGroupAuctionBuyer + @JsonProperty("igs") + List interestGroupAuctionSeller + InterestGroupAuctionIntentExt ext +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntentExt.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntentExt.groovy new file mode 100644 index 00000000000..29aeaf980da --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntentExt.groovy @@ -0,0 +1,11 @@ +package org.prebid.server.functional.model.response.auction + +import groovy.transform.ToString +import org.prebid.server.functional.model.bidder.BidderName + +@ToString(includeNames = true, ignoreNulls = true) +class InterestGroupAuctionIntentExt { + + BidderName bidder + BidderName adapter +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSeller.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSeller.groovy new file mode 100644 index 00000000000..192f5c2f611 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSeller.groovy @@ -0,0 +1,14 @@ +package org.prebid.server.functional.model.response.auction + +import com.fasterxml.jackson.databind.PropertyNamingStrategies +import com.fasterxml.jackson.databind.annotation.JsonNaming +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) +class InterestGroupAuctionSeller { + + String impId + Map config + InterestGroupAuctionSellerExt ext +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSellerExt.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSellerExt.groovy new file mode 100644 index 00000000000..fcecf1b5480 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSellerExt.groovy @@ -0,0 +1,10 @@ +package org.prebid.server.functional.model.response.auction + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class InterestGroupAuctionSellerExt { + + String bidder + String adapter +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponse.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponse.groovy index 2ba60b226c1..b5d5289d5a6 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponse.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponse.groovy @@ -1,6 +1,5 @@ package org.prebid.server.functional.model.response.auction - import groovy.transform.ToString import org.prebid.server.functional.model.request.auction.BidRequest diff --git a/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy index cab50bd816b..35af8e2e0cd 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy @@ -6,6 +6,7 @@ import org.prebid.server.functional.model.db.Account import org.prebid.server.functional.model.db.StoredImp import org.prebid.server.functional.model.db.StoredRequest import org.prebid.server.functional.model.request.amp.AmpRequest +import org.prebid.server.functional.model.request.auction.AuctionEnvironment import org.prebid.server.functional.model.request.auction.Banner import org.prebid.server.functional.model.request.auction.BidRequest import org.prebid.server.functional.model.request.auction.Device @@ -15,6 +16,7 @@ import org.prebid.server.functional.model.request.auction.Imp import org.prebid.server.functional.model.request.auction.ImpExt import org.prebid.server.functional.model.request.auction.ImpExtContext import org.prebid.server.functional.model.request.auction.ImpExtContextData +import org.prebid.server.functional.model.request.auction.InterestGroupAuctionSupport import org.prebid.server.functional.model.request.auction.Native import org.prebid.server.functional.model.request.auction.PrebidStoredRequest import org.prebid.server.functional.model.request.auction.Site @@ -34,6 +36,10 @@ import static org.prebid.server.functional.model.bidder.BidderName.APPNEXUS import static org.prebid.server.functional.model.bidder.CompressionType.GZIP import static org.prebid.server.functional.model.bidder.CompressionType.NONE import static org.prebid.server.functional.model.request.auction.Asset.titleAsset +import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.DEVICE_ORCHESTRATED +import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.NOT_SUPPORTED +import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.SERVER_ORCHESTRATED +import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.UNKNOWN import static org.prebid.server.functional.model.request.auction.DistributionChannel.APP import static org.prebid.server.functional.model.request.auction.DistributionChannel.DOOH import static org.prebid.server.functional.model.request.auction.DistributionChannel.SITE @@ -847,7 +853,7 @@ class BidderParamsSpec extends BaseSpec { def "PBS should send request to bidder when adapters.bidder.aliases.bidder.meta-info.currency-accepted not specified"() { given: "PBS with adapter configuration" def pbsService = pbsServiceFactory.getService( - "adapters.generic.aliases.alias.enabled" : "true", + "adapters.generic.aliases.alias.enabled": "true", "adapters.generic.aliases.alias.endpoint": "$networkServiceContainer.rootUri/auction".toString(), "adapters.generic.aliases.alias.meta-info.currency-accepted": "") @@ -955,7 +961,7 @@ class BidderParamsSpec extends BaseSpec { def "PBS should send request to bidder when adapters.bidder.aliases.bidder.meta-info.currency-accepted intersect with requested currency"() { given: "PBS with adapter configuration" def pbsService = pbsServiceFactory.getService( - "adapters.generic.aliases.alias.enabled" : "true", + "adapters.generic.aliases.alias.enabled": "true", "adapters.generic.aliases.alias.endpoint": "$networkServiceContainer.rootUri/auction".toString(), "adapters.generic.aliases.alias.meta-info.currency-accepted": "${USD},${EUR}".toString()) @@ -996,7 +1002,7 @@ class BidderParamsSpec extends BaseSpec { def "PBS shouldn't send request to bidder and emit warning when adapters.bidder.aliases.bidder.meta-info.currency-accepted not intersect with requested currency"() { given: "PBS with adapter configuration" def pbsService = pbsServiceFactory.getService( - "adapters.generic.aliases.alias.enabled" : "true", + "adapters.generic.aliases.alias.enabled": "true", "adapters.generic.aliases.alias.endpoint": "$networkServiceContainer.rootUri/auction".toString(), "adapters.generic.aliases.alias.meta-info.currency-accepted": "${JPY},${CHF}".toString()) @@ -1040,4 +1046,66 @@ class BidderParamsSpec extends BaseSpec { assert seatNonBid.nonBid[0].impId == bidRequest.imp[0].id assert seatNonBid.nonBid[0].statusCode == REQUEST_BLOCKED_UNACCEPTABLE_CURRENCY } + + def "PBS should pass imp.ext.ae to imp.ext.igs.ae when imp.ext.ae specified and imp.ext.igs.ae doesn't specified"() { + given: "Default bid request with populated imp.ext" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.tap { + ae = auctionEnvironment + interestGroupAuctionSupport = new InterestGroupAuctionSupport(auctionEnvironment: null) + } + } + + when: "PBS processes auction request" + defaultPbsService.sendAuctionRequest(bidRequest) + + then: "Bidder request should imp[].{ae/ext.igs.ae} same value as requested" + def bidderRequest = bidder.getBidderRequest(bidRequest.id) + assert bidderRequest.imp[0].ext.ae == auctionEnvironment + assert bidderRequest.imp[0].ext.interestGroupAuctionSupport.auctionEnvironment == auctionEnvironment + + where: + auctionEnvironment << [NOT_SUPPORTED, DEVICE_ORCHESTRATED] + } + + def "PBS shouldn't pass imp.ext.ae to imp.ext.igs.ae when imp.ext.ae specified and contain not a 0 or 1"() { + given: "Default bid request with populated imp.ext" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.tap { + ae = auctionEnvironment + interestGroupAuctionSupport = new InterestGroupAuctionSupport(auctionEnvironment: null) + } + } + + when: "PBS processes auction request" + defaultPbsService.sendAuctionRequest(bidRequest) + + then: "Bidder request should imp[].ae same value as requested" + def bidderRequest = bidder.getBidderRequest(bidRequest.id) + assert bidderRequest.imp[0].ext.ae == auctionEnvironment + assert !bidderRequest.imp[0].ext.interestGroupAuctionSupport.auctionEnvironment + + where: + auctionEnvironment << [SERVER_ORCHESTRATED, UNKNOWN] + } + + def "PBS shouldn't pass imp.ext.ae to imp.ext.igs.ae when imp.ext.ae and imp.ext.igs.ae specified"() { + given: "Default bid request with populated imp.ext" + def extAuctionEnv = PBSUtils.getRandomEnum(AuctionEnvironment) + def extIgsAuctionEnv = PBSUtils.getRandomEnum(AuctionEnvironment) + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.tap { + ae = extAuctionEnv + interestGroupAuctionSupport = new InterestGroupAuctionSupport(auctionEnvironment: extIgsAuctionEnv) + } + } + + when: "PBS processes auction request" + defaultPbsService.sendAuctionRequest(bidRequest) + + then: "Bidder request should imp[].{ae/ext.igs.ae} same value as requested" + def bidderRequest = bidder.getBidderRequest(bidRequest.id) + assert bidderRequest.imp[0].ext.ae == extAuctionEnv + assert bidderRequest.imp[0].ext.interestGroupAuctionSupport.auctionEnvironment == extIgsAuctionEnv + } } diff --git a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy index 45540134252..705c300ef28 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy @@ -1,7 +1,13 @@ package org.prebid.server.functional.tests.bidder.openx import org.prebid.server.functional.model.bidder.Openx +import org.prebid.server.functional.model.config.AccountAuctionConfig +import org.prebid.server.functional.model.config.AccountConfig +import org.prebid.server.functional.model.db.Account import org.prebid.server.functional.model.request.auction.BidRequest +import org.prebid.server.functional.model.response.auction.InterestGroupAuctionBuyer +import org.prebid.server.functional.model.response.auction.InterestGroupAuctionIntent +import org.prebid.server.functional.model.response.auction.InterestGroupAuctionSeller import org.prebid.server.functional.model.response.auction.OpenxBidResponse import org.prebid.server.functional.model.response.auction.OpenxBidResponseExt import org.prebid.server.functional.service.PrebidServerService @@ -9,6 +15,11 @@ import org.prebid.server.functional.tests.BaseSpec import org.prebid.server.functional.util.PBSUtils import spock.lang.Shared +import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.NOT_SUPPORTED +import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.DEVICE_ORCHESTRATED +import static org.prebid.server.functional.model.request.auction.PaaFormant.IAB +import static org.prebid.server.functional.model.request.auction.PaaFormant.ORIGINAL +import static org.prebid.server.functional.model.response.auction.ErrorType.PREBID import static org.prebid.server.functional.testcontainers.Dependencies.networkServiceContainer class OpenxSpec extends BaseSpec { @@ -22,7 +33,7 @@ class OpenxSpec extends BaseSpec { def "PBS should populate fledge config when bid response with fledge and imp[0].ext.ae = 1"() { given: "Default basic BidRequest with ae and openx bidder" def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = 1 + imp[0].ext.ae = DEVICE_ORCHESTRATED imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx } @@ -53,7 +64,7 @@ class OpenxSpec extends BaseSpec { def "PBS shouldn't populate fledge config when imp[0].ext.ae = 0"() { given: "Default basic BidRequest without ae" def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = 0 + imp[0].ext.ae = NOT_SUPPORTED imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx } @@ -78,7 +89,7 @@ class OpenxSpec extends BaseSpec { def "PBS shouldn't populate fledge config when imp[0].ext.ae = 1 and bid response didn't return fledge config"() { given: "Default basic BidRequest without ae" def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = 1 + imp[0].ext.ae = DEVICE_ORCHESTRATED imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx } @@ -98,4 +109,480 @@ class OpenxSpec extends BaseSpec { then: "PBS response shouldn't contain fledge config" assert !response.ext.prebid.fledge } + + def "PBS should populate fledge and iab output config when bid response with fledge and paa formant iab"() { + given: "Default bid request with openx" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.ae = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + ext.prebid.paaFormat = requestPaaFormant + } + + and: "Default bid response with fledge config" + def impId = bidRequest.imp[0].id + def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { + ext = new OpenxBidResponseExt().tap { + fledgeAuctionConfigs = [(impId): fledgeConfig] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + and: "Save account in the DB" + def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) + def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) + accountDao.save(account) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response should contain fledge config" + def auctionConfigs = response.ext?.prebid?.fledge?.auctionConfigs + assert auctionConfigs?.size() == 1 + assert auctionConfigs[0].impId == impId + assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value + assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value + assert auctionConfigs[0].config == fledgeConfig + + and: "PBS response should contain igs config" + def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] + assert interestGroupAuctionSeller.impId == impId + assert interestGroupAuctionSeller.config == fledgeConfig + assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value + + where: + accountPaaFormat | requestPaaFormant + IAB | IAB + null | IAB + IAB | null + } + + def "PBS should populate iab output config when bid response with igi and paa format iab"() { + given: "Default basic BidRequest with ae and openx bidder" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.ae = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + ext.prebid.paaFormat = requestPaaFormant + } + + and: "Default bid response with igs config" + def impId = bidRequest.imp[0].id + def igsConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def igbConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def igbOrigin = PBSUtils.randomString + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { + ext = new OpenxBidResponseExt().tap { + interestGroupAuctionIntent = [new InterestGroupAuctionIntent( + impId: impId, + interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: impId, config: igsConfig)], + interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: PBSUtils.randomString, pbs: igbConfig)])] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + and: "Save account in the DB" + def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) + def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) + accountDao.save(account) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response should contain igs config" + def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] + assert interestGroupAuctionSeller.impId == impId + assert interestGroupAuctionSeller.config == igsConfig + assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value + + and: "PBS response should contain igb config" + def interestGroupAuctionBuyer = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] + assert interestGroupAuctionBuyer.ext.bidder == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionBuyer.ext.adapter == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionBuyer.origin == igbOrigin + assert interestGroupAuctionBuyer.pbs == igbConfig + + and: "PBS shouldn't contain warning" + assert !bidResponse.ext.warnings[PREBID] + + and: "PBS shouldn't emit log" + assert !pbsService.getLogsByValue("DROP igb obj") + + and: "PBS shouldn't emit metric" + def metricsRequest = pbsService.sendCollectedMetricsRequest() + assert !metricsRequest["Some name of metric for dropped igb object"] + + where: + accountPaaFormat | requestPaaFormant + IAB | IAB + null | IAB + IAB | null + } + + def "PBS should populate igb when bidder supplies interest group auction intent and paa formant iab"() { + given: "Default basic bidRequest" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.ae = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + ext.prebid.paaFormat = IAB + } + + and: "Default bid response with igs config" + def impId = bidRequest.imp[0].id + def igsConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def igbConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def igbOrigin = PBSUtils.randomString + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { + ext = new OpenxBidResponseExt().tap { + interestGroupAuctionIntent = [new InterestGroupAuctionIntent( + impId: impId, + interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: igsImpId, config: igsConfig)], + interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: PBSUtils.randomString, pbs: igbConfig)])] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response should contain igs config" + def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] + assert interestGroupAuctionSeller.impId == igsImpId + assert interestGroupAuctionSeller.config == igsConfig + assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value + + and: "PBS response should contain igb config" + def interestGroupAuctionBuyer = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] + assert interestGroupAuctionBuyer.ext.bidder == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionBuyer.ext.adapter == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionBuyer.origin == igbOrigin + assert interestGroupAuctionBuyer.pbs == igbConfig + + and: "PBS shouldn't contain warning" + assert !bidResponse.ext.warnings[PREBID] + + and: "PBS shouldn't emit log" + assert !pbsService.getLogsByValue("DROP igb obj") + + and: "PBS shouldn't emit metric" + def metricsRequest = pbsService.sendCollectedMetricsRequest() + assert !metricsRequest["Some name of metric for dropped igb object"] + + where: + igsImpId | igsConfig + bidRequest.imp[0].id | [(PBSUtils.randomString): PBSUtils.randomString] + null | [(PBSUtils.randomString): PBSUtils.randomString] + bidRequest.imp[0].id | null + } + + def "PBS should drop igb object and emit warning and log metric when bidder supplies iab formant without igi.impId"() { + given: "Default basic BidRequest with ae and openx bidder" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.ae = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + ext.prebid.paaFormat = requestPaaFormant + } + + and: "Default bid response with interest group auction intent" + def impId = bidRequest.imp[0].id + def config = [(PBSUtils.randomString): PBSUtils.randomString] + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { + ext = new OpenxBidResponseExt().tap { + interestGroupAuctionIntent = [new InterestGroupAuctionIntent( + impId: null, + interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: impId, config: config)], + interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: PBSUtils.randomString, + pbs: [(PBSUtils.randomString): PBSUtils.randomString])] + )] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + and: "Save account in the DB" + def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) + def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) + accountDao.save(account) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response should contain igs config" + def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] + assert interestGroupAuctionSeller.impId == impId + assert interestGroupAuctionSeller.config == config + assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value + + and: "PBS response shouldn't contain igb config" + assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] + + and: "PBS should contain warning" + def warningEntries = bidResponse.ext.warnings[PREBID] + assert warningEntries[0].code == 11 + assert warningEntries[0].message == "Some message" + + and: "PBS should emit log" + def logsByValue = pbsService.getLogsByValue("DROP igb obj") + assert logsByValue == "Some sentence" + + and: "PBS should emit metric" + def metricsRequest = pbsService.sendCollectedMetricsRequest() + assert metricsRequest["Some name of metric for dropped igb object"] == 1 + + where: + accountPaaFormat | requestPaaFormant + IAB | IAB + null | IAB + IAB | null + } + + def "PBS should drop igs and emit warning and log metric when bidder supplies iab formant without igs[].{impId,config}"() { + given: "Default bid request with openx bidder" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.ae = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + ext.prebid.paaFormat = requestPaaFormant + } + + and: "Default bid response with igs config" + def impId = bidRequest.imp[0].id + def igbOrigin = PBSUtils.randomString + def igbConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { + ext = new OpenxBidResponseExt().tap { + interestGroupAuctionIntent = [new InterestGroupAuctionIntent( + impId: impId, + interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: null, config: null)], + interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: igbOrigin, pbs: igbConfig)] + )] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + and: "Save account in the DB" + def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) + def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) + accountDao.save(account) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response shouldn't contain igs config" + assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] + + and: "PBS response should contain igb config" + def interestGroupAuctionBuyer = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] + assert interestGroupAuctionBuyer.ext.bidder == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionBuyer.ext.adapter == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionBuyer.origin == igbOrigin + assert interestGroupAuctionBuyer.pbs == igbConfig + + and: "PBS should contain warning" + def warningEntries = bidResponse.ext.warnings[PREBID] + assert warningEntries[0].code == 11 + assert warningEntries[0].message == "Some message" + + and: "PBS should emit log" + def logsByValue = pbsService.getLogsByValue("DROP igb obj") + assert logsByValue == "Some sentence" + + and: "Alert.general metric should be updated" + def metricsRequest = pbsService.sendCollectedMetricsRequest() + assert metricsRequest["alerts.general" as String] == 1 + + where: + accountPaaFormat | requestPaaFormant + IAB | IAB + null | IAB + IAB | null + } + + def "PBS should populate fledge when bidder supplies auction configs in response and paa formant original"() { + given: "Default bid request with opex bidder" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.ae = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + ext.prebid.paaFormat = requestPaaFormant + } + + and: "Default bid response with fledge config" + def impId = bidRequest.imp[0].id + def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { + ext = new OpenxBidResponseExt().tap { + fledgeAuctionConfigs = [(impId): fledgeConfig] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + and: "Save account in the DB" + def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) + def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) + accountDao.save(account) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response should contain fledge config" + def auctionConfigs = response.ext?.prebid?.fledge?.auctionConfigs + assert auctionConfigs?.size() == 1 + assert auctionConfigs[0].impId == impId + assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value + assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value + assert auctionConfigs[0].config == fledgeConfig + + and: "PBS response shouldn't contain igs config" + assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] + + where: + accountPaaFormat | requestPaaFormant + ORIGINAL | ORIGINAL + null | ORIGINAL + ORIGINAL | null + } + + def "PBS shouldn't populate fledge config when bidder supplies interest group auction intent without impId and config and paa format original"() { + given: "Default bid request with openx" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.ae = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + ext.prebid.paaFormat = requestPaaFormant + } + + and: "Default bid response with igs and empty igs" + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { + ext = new OpenxBidResponseExt().tap { + interestGroupAuctionIntent = [new InterestGroupAuctionIntent( + impId: bidRequest.imp[0].id, + interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: null, config: null)], + interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: PBSUtils.randomString, pbs: [(PBSUtils.randomString): PBSUtils.randomString])] + )] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + and: "Save account in the DB" + def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) + def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) + accountDao.save(account) + + and: "Flush metrics" + flushMetrics(pbsService) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response shouldn't contain fledge config" + assert !response.ext?.prebid?.fledge?.auctionConfigs + + and: "PBS response shouldn't contain igs" + assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] + + and: "PBS response shouldn't contain igb" + assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] + + and: "PBS should contain warning" + def warningEntries = bidResponse.ext.warnings[PREBID] + assert warningEntries[0].code == 11 + assert warningEntries[0].message == "Some error warning" + + and: "PBS should emit log" + def logsByValue = pbsService.getLogsByValue("DROP igb obj") + assert logsByValue == "Some warning message" + + and: "Alert.general metric should be updated" + def metricsRequest = pbsService.sendCollectedMetricsRequest() + assert metricsRequest["alerts.general"] == 1 + + where: + accountPaaFormat | requestPaaFormant + ORIGINAL | ORIGINAL + null | ORIGINAL + ORIGINAL | null + } + + def "PBS should populate fledge auction config when bidder supplies interest group auction intent and paa format original"() { + given: "Default bid request with openx" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.ae = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + ext.prebid.paaFormat = requestPaaFormant + } + + and: "Default bid response with interest group auction intent" + def impId = bidRequest.imp[0].id + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { + ext = new OpenxBidResponseExt().tap { + interestGroupAuctionIntent = [new InterestGroupAuctionIntent( + impId: impId, + interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: igsImpId, config: igsConfig)], + interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: PBSUtils.randomString, pbs: [(PBSUtils.randomString): PBSUtils.randomString])] + )] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + and: "Save account in the DB" + def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) + def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) + accountDao.save(account) + + and: "Flush metrics" + flushMetrics(pbsService) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response should contain igs config" + def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] + assert interestGroupAuctionSeller.impId == igsImpId + assert interestGroupAuctionSeller.config == igsConfig + assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value + + and: "PBS response should contain fledge config" + def auctionConfigs = response.ext?.prebid?.fledge?.auctionConfigs + assert auctionConfigs?.size() == 1 + assert auctionConfigs[0].impId == igsImpId + assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value + assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value + assert auctionConfigs[0].config == igsConfig + + and: "PBS response shouldn't contain igb config" + assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] + + and: "Alerts.general metrics shouldn't be populated" + def metrics = pbsService.sendCollectedMetricsRequest() + assert !metrics["alerts.general"] + + and: "Bid response shouldn't contain warnings" + assert !bidResponse.ext.warnings + + and: "PBS shouldn't emit log" + assert !pbsService.getLogsByValue("DROP igs obj") + + where: + accountPaaFormat | requestPaaFormant | igsImpId | igsConfig + ORIGINAL | ORIGINAL | bidRequest.imp[0].id | [(PBSUtils.randomString): PBSUtils.randomString] + null | ORIGINAL | null | [(PBSUtils.randomString): PBSUtils.randomString] + ORIGINAL | null | bidRequest.imp[0].id | null + } } From f4f855c825fa302b5aee2eafbe587b4cf7e04637 Mon Sep 17 00:00:00 2001 From: markiian Date: Mon, 16 Dec 2024 16:42:48 +0200 Subject: [PATCH 2/7] Minor update func test --- .../prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy index 705c300ef28..75cd6e70143 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy @@ -234,7 +234,6 @@ class OpenxSpec extends BaseSpec { and: "Default bid response with igs config" def impId = bidRequest.imp[0].id - def igsConfig = [(PBSUtils.randomString): PBSUtils.randomString] def igbConfig = [(PBSUtils.randomString): PBSUtils.randomString] def igbOrigin = PBSUtils.randomString def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { From e5f231067763d2cd2d6a6ef82c64220561e8a4f9 Mon Sep 17 00:00:00 2001 From: markiian Date: Tue, 14 Jan 2025 11:56:49 +0200 Subject: [PATCH 3/7] Update after review --- .../model/config/AccountAuctionConfig.groovy | 4 +- .../model/request/auction/ImpExt.groovy | 2 +- .../{PaaFormant.groovy => PaaFormat.groovy} | 2 +- .../model/request/auction/Prebid.groovy | 2 +- .../functional/tests/BidderParamsSpec.groovy | 14 +- .../tests/bidder/openx/OpenxSpec.groovy | 466 ++---------------- 6 files changed, 44 insertions(+), 446 deletions(-) rename src/test/groovy/org/prebid/server/functional/model/request/auction/{PaaFormant.groovy => PaaFormat.groovy} (92%) diff --git a/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy b/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy index 2233c6b8fe0..8dc9831e3fa 100644 --- a/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy @@ -6,7 +6,7 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming import groovy.transform.ToString import org.prebid.server.functional.model.bidder.BidderName import org.prebid.server.functional.model.request.auction.BidAdjustment -import org.prebid.server.functional.model.request.auction.PaaFormant +import org.prebid.server.functional.model.request.auction.PaaFormat import org.prebid.server.functional.model.request.auction.Targeting import org.prebid.server.functional.model.response.auction.MediaType @@ -24,7 +24,7 @@ class AccountAuctionConfig { AccountEventsConfig events AccountPriceFloorsConfig priceFloors Targeting targeting - PaaFormant paaformat + PaaFormat paaformat @JsonProperty("preferredmediatype") Map preferredMediaType @JsonProperty("privacysandbox") diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy index 7bf15ce0d34..afbc898691b 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy @@ -28,7 +28,7 @@ class ImpExt { String skadn String general @JsonProperty("igs") - InterestGroupAuctionSupport interestGroupAuctionSupport + List interestGroupAuctionSupports AnyUnsupportedBidder anyUnsupportedBidder static ImpExt getDefaultImpExt() { diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormant.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormat.groovy similarity index 92% rename from src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormant.groovy rename to src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormat.groovy index 5d95dc9db91..948f63806b1 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormant.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormat.groovy @@ -2,7 +2,7 @@ package org.prebid.server.functional.model.request.auction import com.fasterxml.jackson.annotation.JsonValue -enum PaaFormant { +enum PaaFormat { ORIGINAL, IAB diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy index e2f560ccba8..0e021bb4598 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy @@ -40,7 +40,7 @@ class Prebid { PrebidModulesConfig modules PrebidAnalytics analytics StoredAuctionResponse storedAuctionResponse - PaaFormant paaFormat + PaaFormat paaFormat static class Channel { diff --git a/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy index 35af8e2e0cd..fe7a0c413b6 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy @@ -787,7 +787,7 @@ class BidderParamsSpec extends BaseSpec { def impExt = ImpExt.getDefaultImpExt().tap { prebid.bidder.generic = null generic = new Generic() - ae = PBSUtils.randomNumber + ae = PBSUtils.getRandomEnum(AuctionEnvironment) all = PBSUtils.randomNumber context = new ImpExtContext(data: new ImpExtContextData()) data = new ImpExtContextData(pbAdSlot: PBSUtils.randomString) @@ -1052,7 +1052,7 @@ class BidderParamsSpec extends BaseSpec { def bidRequest = BidRequest.defaultBidRequest.tap { imp[0].ext.tap { ae = auctionEnvironment - interestGroupAuctionSupport = new InterestGroupAuctionSupport(auctionEnvironment: null) + interestGroupAuctionSupports = [new InterestGroupAuctionSupport(auctionEnvironment: null)] } } @@ -1062,7 +1062,7 @@ class BidderParamsSpec extends BaseSpec { then: "Bidder request should imp[].{ae/ext.igs.ae} same value as requested" def bidderRequest = bidder.getBidderRequest(bidRequest.id) assert bidderRequest.imp[0].ext.ae == auctionEnvironment - assert bidderRequest.imp[0].ext.interestGroupAuctionSupport.auctionEnvironment == auctionEnvironment + assert bidderRequest.imp[0].ext.interestGroupAuctionSupports[0].auctionEnvironment == auctionEnvironment where: auctionEnvironment << [NOT_SUPPORTED, DEVICE_ORCHESTRATED] @@ -1073,7 +1073,7 @@ class BidderParamsSpec extends BaseSpec { def bidRequest = BidRequest.defaultBidRequest.tap { imp[0].ext.tap { ae = auctionEnvironment - interestGroupAuctionSupport = new InterestGroupAuctionSupport(auctionEnvironment: null) + interestGroupAuctionSupports = [new InterestGroupAuctionSupport(auctionEnvironment: null)] } } @@ -1083,7 +1083,7 @@ class BidderParamsSpec extends BaseSpec { then: "Bidder request should imp[].ae same value as requested" def bidderRequest = bidder.getBidderRequest(bidRequest.id) assert bidderRequest.imp[0].ext.ae == auctionEnvironment - assert !bidderRequest.imp[0].ext.interestGroupAuctionSupport.auctionEnvironment + assert !bidderRequest.imp[0].ext.interestGroupAuctionSupports[0].auctionEnvironment where: auctionEnvironment << [SERVER_ORCHESTRATED, UNKNOWN] @@ -1096,7 +1096,7 @@ class BidderParamsSpec extends BaseSpec { def bidRequest = BidRequest.defaultBidRequest.tap { imp[0].ext.tap { ae = extAuctionEnv - interestGroupAuctionSupport = new InterestGroupAuctionSupport(auctionEnvironment: extIgsAuctionEnv) + interestGroupAuctionSupports = [new InterestGroupAuctionSupport(auctionEnvironment: extIgsAuctionEnv)] } } @@ -1106,6 +1106,6 @@ class BidderParamsSpec extends BaseSpec { then: "Bidder request should imp[].{ae/ext.igs.ae} same value as requested" def bidderRequest = bidder.getBidderRequest(bidRequest.id) assert bidderRequest.imp[0].ext.ae == extAuctionEnv - assert bidderRequest.imp[0].ext.interestGroupAuctionSupport.auctionEnvironment == extIgsAuctionEnv + assert bidderRequest.imp[0].ext.interestGroupAuctionSupports[0].auctionEnvironment == extIgsAuctionEnv } } diff --git a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy index 75cd6e70143..892412f5b10 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy @@ -5,9 +5,6 @@ import org.prebid.server.functional.model.config.AccountAuctionConfig import org.prebid.server.functional.model.config.AccountConfig import org.prebid.server.functional.model.db.Account import org.prebid.server.functional.model.request.auction.BidRequest -import org.prebid.server.functional.model.response.auction.InterestGroupAuctionBuyer -import org.prebid.server.functional.model.response.auction.InterestGroupAuctionIntent -import org.prebid.server.functional.model.response.auction.InterestGroupAuctionSeller import org.prebid.server.functional.model.response.auction.OpenxBidResponse import org.prebid.server.functional.model.response.auction.OpenxBidResponseExt import org.prebid.server.functional.service.PrebidServerService @@ -15,11 +12,11 @@ import org.prebid.server.functional.tests.BaseSpec import org.prebid.server.functional.util.PBSUtils import spock.lang.Shared -import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.NOT_SUPPORTED +import static org.prebid.server.functional.model.bidder.BidderName.OPENX import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.DEVICE_ORCHESTRATED -import static org.prebid.server.functional.model.request.auction.PaaFormant.IAB -import static org.prebid.server.functional.model.request.auction.PaaFormant.ORIGINAL -import static org.prebid.server.functional.model.response.auction.ErrorType.PREBID +import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.NOT_SUPPORTED +import static org.prebid.server.functional.model.request.auction.PaaFormat.IAB +import static org.prebid.server.functional.model.request.auction.PaaFormat.ORIGINAL import static org.prebid.server.functional.testcontainers.Dependencies.networkServiceContainer class OpenxSpec extends BaseSpec { @@ -30,7 +27,7 @@ class OpenxSpec extends BaseSpec { @Shared PrebidServerService pbsService = pbsServiceFactory.getService(OPENX_CONFIG) - def "PBS should populate fledge config when bid response with fledge and imp[0].ext.ae = 1"() { + def "PBS should populate fledge config by default when bid response with fledge"() { given: "Default basic BidRequest with ae and openx bidder" def bidRequest = BidRequest.defaultBidRequest.tap { imp[0].ext.ae = DEVICE_ORCHESTRATED @@ -40,7 +37,7 @@ class OpenxSpec extends BaseSpec { and: "Default bid response with fledge config" def impId = bidRequest.imp[0].id def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { ext = new OpenxBidResponseExt().tap { fledgeAuctionConfigs = [(impId): fledgeConfig] } @@ -61,67 +58,18 @@ class OpenxSpec extends BaseSpec { assert auctionConfigs[0].config == fledgeConfig } - def "PBS shouldn't populate fledge config when imp[0].ext.ae = 0"() { - given: "Default basic BidRequest without ae" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = NOT_SUPPORTED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - } - - and: "Default bid response" - def impId = bidRequest.imp[0].id - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = [(impId): [(PBSUtils.randomString): PBSUtils.randomString]] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response shouldn't contain fledge config" - assert !response.ext.prebid.fledge - } - - def "PBS shouldn't populate fledge config when imp[0].ext.ae = 1 and bid response didn't return fledge config"() { - given: "Default basic BidRequest without ae" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - } - - and: "Default bid response" - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = null - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response shouldn't contain fledge config" - assert !response.ext.prebid.fledge - } - - def "PBS should populate fledge and iab output config when bid response with fledge and paa formant iab"() { - given: "Default bid request with openx" + def "PBS should populate fledge config when bid response with fledge and ext.prebid.paaFormat = ORIGINAL"() { + given: "Default basic BidRequest with ae and openx bidder" def bidRequest = BidRequest.defaultBidRequest.tap { imp[0].ext.ae = DEVICE_ORCHESTRATED imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = requestPaaFormant + ext.prebid.paaFormat = ORIGINAL } and: "Default bid response with fledge config" def impId = bidRequest.imp[0].id def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { ext = new OpenxBidResponseExt().tap { fledgeAuctionConfigs = [(impId): fledgeConfig] } @@ -130,11 +78,6 @@ class OpenxSpec extends BaseSpec { and: "Set bidder response" bidder.setResponse(bidRequest.id, bidResponse) - and: "Save account in the DB" - def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) - def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) - accountDao.save(account) - when: "PBS processes auction request" def response = pbsService.sendAuctionRequest(bidRequest) @@ -145,273 +88,60 @@ class OpenxSpec extends BaseSpec { assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value assert auctionConfigs[0].config == fledgeConfig - - and: "PBS response should contain igs config" - def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - assert interestGroupAuctionSeller.impId == impId - assert interestGroupAuctionSeller.config == fledgeConfig - assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value - - where: - accountPaaFormat | requestPaaFormant - IAB | IAB - null | IAB - IAB | null - } - - def "PBS should populate iab output config when bid response with igi and paa format iab"() { - given: "Default basic BidRequest with ae and openx bidder" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = requestPaaFormant - } - - and: "Default bid response with igs config" - def impId = bidRequest.imp[0].id - def igsConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def igbConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def igbOrigin = PBSUtils.randomString - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { - ext = new OpenxBidResponseExt().tap { - interestGroupAuctionIntent = [new InterestGroupAuctionIntent( - impId: impId, - interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: impId, config: igsConfig)], - interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: PBSUtils.randomString, pbs: igbConfig)])] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - and: "Save account in the DB" - def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) - def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) - accountDao.save(account) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response should contain igs config" - def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - assert interestGroupAuctionSeller.impId == impId - assert interestGroupAuctionSeller.config == igsConfig - assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value - - and: "PBS response should contain igb config" - def interestGroupAuctionBuyer = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] - assert interestGroupAuctionBuyer.ext.bidder == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionBuyer.ext.adapter == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionBuyer.origin == igbOrigin - assert interestGroupAuctionBuyer.pbs == igbConfig - - and: "PBS shouldn't contain warning" - assert !bidResponse.ext.warnings[PREBID] - - and: "PBS shouldn't emit log" - assert !pbsService.getLogsByValue("DROP igb obj") - - and: "PBS shouldn't emit metric" - def metricsRequest = pbsService.sendCollectedMetricsRequest() - assert !metricsRequest["Some name of metric for dropped igb object"] - - where: - accountPaaFormat | requestPaaFormant - IAB | IAB - null | IAB - IAB | null } - def "PBS should populate igb when bidder supplies interest group auction intent and paa formant iab"() { - given: "Default basic bidRequest" + def "PBS shouldn't populate fledge config when bid response with fledge and ext.prebid.paaFormat = IAB"() { + given: "Default basic BidRequest without ae" def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = DEVICE_ORCHESTRATED + imp[0].ext.ae = NOT_SUPPORTED imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx ext.prebid.paaFormat = IAB } - and: "Default bid response with igs config" - def impId = bidRequest.imp[0].id - def igbConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def igbOrigin = PBSUtils.randomString - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { - ext = new OpenxBidResponseExt().tap { - interestGroupAuctionIntent = [new InterestGroupAuctionIntent( - impId: impId, - interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: igsImpId, config: igsConfig)], - interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: PBSUtils.randomString, pbs: igbConfig)])] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response should contain igs config" - def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - assert interestGroupAuctionSeller.impId == igsImpId - assert interestGroupAuctionSeller.config == igsConfig - assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value - - and: "PBS response should contain igb config" - def interestGroupAuctionBuyer = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] - assert interestGroupAuctionBuyer.ext.bidder == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionBuyer.ext.adapter == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionBuyer.origin == igbOrigin - assert interestGroupAuctionBuyer.pbs == igbConfig - - and: "PBS shouldn't contain warning" - assert !bidResponse.ext.warnings[PREBID] - - and: "PBS shouldn't emit log" - assert !pbsService.getLogsByValue("DROP igb obj") - - and: "PBS shouldn't emit metric" - def metricsRequest = pbsService.sendCollectedMetricsRequest() - assert !metricsRequest["Some name of metric for dropped igb object"] - - where: - igsImpId | igsConfig - bidRequest.imp[0].id | [(PBSUtils.randomString): PBSUtils.randomString] - null | [(PBSUtils.randomString): PBSUtils.randomString] - bidRequest.imp[0].id | null - } - - def "PBS should drop igb object and emit warning and log metric when bidder supplies iab formant without igi.impId"() { - given: "Default basic BidRequest with ae and openx bidder" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = requestPaaFormant - } - - and: "Default bid response with interest group auction intent" + and: "Default bid response" def impId = bidRequest.imp[0].id - def config = [(PBSUtils.randomString): PBSUtils.randomString] def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { ext = new OpenxBidResponseExt().tap { - interestGroupAuctionIntent = [new InterestGroupAuctionIntent( - impId: null, - interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: impId, config: config)], - interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: PBSUtils.randomString, - pbs: [(PBSUtils.randomString): PBSUtils.randomString])] - )] + fledgeAuctionConfigs = [(impId): [(PBSUtils.randomString): PBSUtils.randomString]] } } and: "Set bidder response" bidder.setResponse(bidRequest.id, bidResponse) - and: "Save account in the DB" - def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) - def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) - accountDao.save(account) - when: "PBS processes auction request" def response = pbsService.sendAuctionRequest(bidRequest) - then: "PBS response should contain igs config" - def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - assert interestGroupAuctionSeller.impId == impId - assert interestGroupAuctionSeller.config == config - assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value - - and: "PBS response shouldn't contain igb config" - assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] - - and: "PBS should contain warning" - def warningEntries = bidResponse.ext.warnings[PREBID] - assert warningEntries[0].code == 11 - assert warningEntries[0].message == "Some message" - - and: "PBS should emit log" - def logsByValue = pbsService.getLogsByValue("DROP igb obj") - assert logsByValue == "Some sentence" - - and: "PBS should emit metric" - def metricsRequest = pbsService.sendCollectedMetricsRequest() - assert metricsRequest["Some name of metric for dropped igb object"] == 1 - - where: - accountPaaFormat | requestPaaFormant - IAB | IAB - null | IAB - IAB | null + then: "PBS response shouldn't contain fledge config" + assert !response.ext.prebid.fledge } - def "PBS should drop igs and emit warning and log metric when bidder supplies iab formant without igs[].{impId,config}"() { - given: "Default bid request with openx bidder" + def "PBS shouldn't populate fledge config when bid response didn't return fledge config"() { + given: "Default basic BidRequest without ae" def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = DEVICE_ORCHESTRATED imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = requestPaaFormant } - and: "Default bid response with igs config" - def impId = bidRequest.imp[0].id - def igbOrigin = PBSUtils.randomString - def igbConfig = [(PBSUtils.randomString): PBSUtils.randomString] + and: "Default bid response" def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { ext = new OpenxBidResponseExt().tap { - interestGroupAuctionIntent = [new InterestGroupAuctionIntent( - impId: impId, - interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: null, config: null)], - interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: igbOrigin, pbs: igbConfig)] - )] + fledgeAuctionConfigs = null } } and: "Set bidder response" bidder.setResponse(bidRequest.id, bidResponse) - and: "Save account in the DB" - def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) - def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) - accountDao.save(account) - when: "PBS processes auction request" def response = pbsService.sendAuctionRequest(bidRequest) - then: "PBS response shouldn't contain igs config" - assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - - and: "PBS response should contain igb config" - def interestGroupAuctionBuyer = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] - assert interestGroupAuctionBuyer.ext.bidder == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionBuyer.ext.adapter == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionBuyer.origin == igbOrigin - assert interestGroupAuctionBuyer.pbs == igbConfig - - and: "PBS should contain warning" - def warningEntries = bidResponse.ext.warnings[PREBID] - assert warningEntries[0].code == 11 - assert warningEntries[0].message == "Some message" - - and: "PBS should emit log" - def logsByValue = pbsService.getLogsByValue("DROP igb obj") - assert logsByValue == "Some sentence" - - and: "Alert.general metric should be updated" - def metricsRequest = pbsService.sendCollectedMetricsRequest() - assert metricsRequest["alerts.general" as String] == 1 - - where: - accountPaaFormat | requestPaaFormant - IAB | IAB - null | IAB - IAB | null + then: "PBS response shouldn't contain fledge config" + assert !response.ext.prebid.fledge } - def "PBS should populate fledge when bidder supplies auction configs in response and paa formant original"() { - given: "Default bid request with opex bidder" + def "PBS should populate fledge and iab output config when bid response with fledge and paa formant IAB"() { + given: "Default bid request with openx" def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = DEVICE_ORCHESTRATED imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx ext.prebid.paaFormat = requestPaaFormant } @@ -436,152 +166,20 @@ class OpenxSpec extends BaseSpec { when: "PBS processes auction request" def response = pbsService.sendAuctionRequest(bidRequest) - then: "PBS response should contain fledge config" - def auctionConfigs = response.ext?.prebid?.fledge?.auctionConfigs - assert auctionConfigs?.size() == 1 - assert auctionConfigs[0].impId == impId - assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value - assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value - assert auctionConfigs[0].config == fledgeConfig - - and: "PBS response shouldn't contain igs config" - assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - - where: - accountPaaFormat | requestPaaFormant - ORIGINAL | ORIGINAL - null | ORIGINAL - ORIGINAL | null - } - - def "PBS shouldn't populate fledge config when bidder supplies interest group auction intent without impId and config and paa format original"() { - given: "Default bid request with openx" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = requestPaaFormant - } - - and: "Default bid response with igs and empty igs" - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { - ext = new OpenxBidResponseExt().tap { - interestGroupAuctionIntent = [new InterestGroupAuctionIntent( - impId: bidRequest.imp[0].id, - interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: null, config: null)], - interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: PBSUtils.randomString, pbs: [(PBSUtils.randomString): PBSUtils.randomString])] - )] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - and: "Save account in the DB" - def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) - def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) - accountDao.save(account) - - and: "Flush metrics" - flushMetrics(pbsService) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - then: "PBS response shouldn't contain fledge config" assert !response.ext?.prebid?.fledge?.auctionConfigs - and: "PBS response shouldn't contain igs" - assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - - and: "PBS response shouldn't contain igb" - assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] - - and: "PBS should contain warning" - def warningEntries = bidResponse.ext.warnings[PREBID] - assert warningEntries[0].code == 11 - assert warningEntries[0].message == "Some error warning" - - and: "PBS should emit log" - def logsByValue = pbsService.getLogsByValue("DROP igb obj") - assert logsByValue == "Some warning message" - - and: "Alert.general metric should be updated" - def metricsRequest = pbsService.sendCollectedMetricsRequest() - assert metricsRequest["alerts.general"] == 1 - - where: - accountPaaFormat | requestPaaFormant - ORIGINAL | ORIGINAL - null | ORIGINAL - ORIGINAL | null - } - - def "PBS should populate fledge auction config when bidder supplies interest group auction intent and paa format original"() { - given: "Default bid request with openx" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = requestPaaFormant - } - - and: "Default bid response with interest group auction intent" - def impId = bidRequest.imp[0].id - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { - ext = new OpenxBidResponseExt().tap { - interestGroupAuctionIntent = [new InterestGroupAuctionIntent( - impId: impId, - interestGroupAuctionSeller: [new InterestGroupAuctionSeller(impId: igsImpId, config: igsConfig)], - interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer(origin: PBSUtils.randomString, pbs: [(PBSUtils.randomString): PBSUtils.randomString])] - )] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - and: "Save account in the DB" - def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) - def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) - accountDao.save(account) - - and: "Flush metrics" - flushMetrics(pbsService) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response should contain igs config" + and: "PBS response should contain igs config" def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - assert interestGroupAuctionSeller.impId == igsImpId - assert interestGroupAuctionSeller.config == igsConfig + assert interestGroupAuctionSeller.impId == impId + assert interestGroupAuctionSeller.config == fledgeConfig assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value - and: "PBS response should contain fledge config" - def auctionConfigs = response.ext?.prebid?.fledge?.auctionConfigs - assert auctionConfigs?.size() == 1 - assert auctionConfigs[0].impId == igsImpId - assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value - assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value - assert auctionConfigs[0].config == igsConfig - - and: "PBS response shouldn't contain igb config" - assert !response.ext.interestGroupAuctionIntent[0].interestGroupAuctionBuyer[0] - - and: "Alerts.general metrics shouldn't be populated" - def metrics = pbsService.sendCollectedMetricsRequest() - assert !metrics["alerts.general"] - - and: "Bid response shouldn't contain warnings" - assert !bidResponse.ext.warnings - - and: "PBS shouldn't emit log" - assert !pbsService.getLogsByValue("DROP igs obj") - where: - accountPaaFormat | requestPaaFormant | igsImpId | igsConfig - ORIGINAL | ORIGINAL | bidRequest.imp[0].id | [(PBSUtils.randomString): PBSUtils.randomString] - null | ORIGINAL | null | [(PBSUtils.randomString): PBSUtils.randomString] - ORIGINAL | null | bidRequest.imp[0].id | null + accountPaaFormat | requestPaaFormant + IAB | IAB + null | IAB + IAB | null } } From 74aefc4ddeef986440e600af5340fe7c5936080c Mon Sep 17 00:00:00 2001 From: markiian Date: Tue, 14 Jan 2025 12:12:04 +0200 Subject: [PATCH 4/7] Update after review --- .../request/auction/AuctionEnvironment.groovy | 4 +-- .../model/request/auction/ImpExt.groovy | 2 +- .../functional/tests/BidderParamsSpec.groovy | 28 +++++++++---------- .../tests/bidder/openx/OpenxSpec.groovy | 6 ++-- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy index 6e779e547cd..f880b7bc634 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy @@ -8,9 +8,7 @@ enum AuctionEnvironment { NOT_SUPPORTED(0), DEVICE_ORCHESTRATED(1), SERVER_ORCHESTRATED(3), - UNKNOWN(PBSUtils.getRandomNumberWithExclusion([NOT_SUPPORTED.value, - DEVICE_ORCHESTRATED.value, - SERVER_ORCHESTRATED.value])), + UNKNOWN(Integer.MAX_VALUE), @JsonValue private int value diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy index afbc898691b..201858525cc 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy @@ -23,7 +23,7 @@ class ImpExt { String tid String gpid String sid - AuctionEnvironment ae + AuctionEnvironment auctionEnvironment String all String skadn String general diff --git a/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy index fe7a0c413b6..61774594b1f 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy @@ -787,7 +787,7 @@ class BidderParamsSpec extends BaseSpec { def impExt = ImpExt.getDefaultImpExt().tap { prebid.bidder.generic = null generic = new Generic() - ae = PBSUtils.getRandomEnum(AuctionEnvironment) + auctionEnvironment = PBSUtils.getRandomEnum(AuctionEnvironment) all = PBSUtils.randomNumber context = new ImpExtContext(data: new ImpExtContextData()) data = new ImpExtContextData(pbAdSlot: PBSUtils.randomString) @@ -807,7 +807,7 @@ class BidderParamsSpec extends BaseSpec { def bidderRequest = bidder.getBidderRequest(bidRequest.id) verifyAll(bidderRequest.imp[0].ext) { bidder == impExt.generic - ae == impExt.ae + auctionEnvironment == impExt.auctionEnvironment all == impExt.all context == impExt.context data == impExt.data @@ -1047,11 +1047,11 @@ class BidderParamsSpec extends BaseSpec { assert seatNonBid.nonBid[0].statusCode == REQUEST_BLOCKED_UNACCEPTABLE_CURRENCY } - def "PBS should pass imp.ext.ae to imp.ext.igs.ae when imp.ext.ae specified and imp.ext.igs.ae doesn't specified"() { + def "PBS should add auction environment to imp.ext.igs when it is present in imp.ext and imp.ext.igs is empty"() { given: "Default bid request with populated imp.ext" def bidRequest = BidRequest.defaultBidRequest.tap { imp[0].ext.tap { - ae = auctionEnvironment + auctionEnvironment = requestedAuctionEnvironment interestGroupAuctionSupports = [new InterestGroupAuctionSupport(auctionEnvironment: null)] } } @@ -1061,18 +1061,18 @@ class BidderParamsSpec extends BaseSpec { then: "Bidder request should imp[].{ae/ext.igs.ae} same value as requested" def bidderRequest = bidder.getBidderRequest(bidRequest.id) - assert bidderRequest.imp[0].ext.ae == auctionEnvironment - assert bidderRequest.imp[0].ext.interestGroupAuctionSupports[0].auctionEnvironment == auctionEnvironment + assert bidderRequest.imp[0].ext.auctionEnvironment == requestedAuctionEnvironment + assert bidderRequest.imp[0].ext.interestGroupAuctionSupports[0].auctionEnvironment == requestedAuctionEnvironment where: - auctionEnvironment << [NOT_SUPPORTED, DEVICE_ORCHESTRATED] + requestedAuctionEnvironment << [NOT_SUPPORTED, DEVICE_ORCHESTRATED] } - def "PBS shouldn't pass imp.ext.ae to imp.ext.igs.ae when imp.ext.ae specified and contain not a 0 or 1"() { + def "PBS shouldn't add unsupported auction environment to imp.ext.igs when it is present in imp.ext and imp.ext.igs is empty"() { given: "Default bid request with populated imp.ext" def bidRequest = BidRequest.defaultBidRequest.tap { imp[0].ext.tap { - ae = auctionEnvironment + auctionEnvironment = requestedAuctionEnvironment interestGroupAuctionSupports = [new InterestGroupAuctionSupport(auctionEnvironment: null)] } } @@ -1082,20 +1082,20 @@ class BidderParamsSpec extends BaseSpec { then: "Bidder request should imp[].ae same value as requested" def bidderRequest = bidder.getBidderRequest(bidRequest.id) - assert bidderRequest.imp[0].ext.ae == auctionEnvironment + assert bidderRequest.imp[0].ext.auctionEnvironment == requestedAuctionEnvironment assert !bidderRequest.imp[0].ext.interestGroupAuctionSupports[0].auctionEnvironment where: - auctionEnvironment << [SERVER_ORCHESTRATED, UNKNOWN] + requestedAuctionEnvironment << [SERVER_ORCHESTRATED, UNKNOWN] } - def "PBS shouldn't pass imp.ext.ae to imp.ext.igs.ae when imp.ext.ae and imp.ext.igs.ae specified"() { + def "PBS shouldn't change auction environment in imp.ext.igs when it is present in both imp.ext and imp.ext.igs"() { given: "Default bid request with populated imp.ext" def extAuctionEnv = PBSUtils.getRandomEnum(AuctionEnvironment) def extIgsAuctionEnv = PBSUtils.getRandomEnum(AuctionEnvironment) def bidRequest = BidRequest.defaultBidRequest.tap { imp[0].ext.tap { - ae = extAuctionEnv + auctionEnvironment = extAuctionEnv interestGroupAuctionSupports = [new InterestGroupAuctionSupport(auctionEnvironment: extIgsAuctionEnv)] } } @@ -1105,7 +1105,7 @@ class BidderParamsSpec extends BaseSpec { then: "Bidder request should imp[].{ae/ext.igs.ae} same value as requested" def bidderRequest = bidder.getBidderRequest(bidRequest.id) - assert bidderRequest.imp[0].ext.ae == extAuctionEnv + assert bidderRequest.imp[0].ext.auctionEnvironment == extAuctionEnv assert bidderRequest.imp[0].ext.interestGroupAuctionSupports[0].auctionEnvironment == extIgsAuctionEnv } } diff --git a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy index 892412f5b10..cb6cbc5bd3f 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy @@ -30,7 +30,7 @@ class OpenxSpec extends BaseSpec { def "PBS should populate fledge config by default when bid response with fledge"() { given: "Default basic BidRequest with ae and openx bidder" def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = DEVICE_ORCHESTRATED + imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx } @@ -61,7 +61,7 @@ class OpenxSpec extends BaseSpec { def "PBS should populate fledge config when bid response with fledge and ext.prebid.paaFormat = ORIGINAL"() { given: "Default basic BidRequest with ae and openx bidder" def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = DEVICE_ORCHESTRATED + imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx ext.prebid.paaFormat = ORIGINAL } @@ -93,7 +93,7 @@ class OpenxSpec extends BaseSpec { def "PBS shouldn't populate fledge config when bid response with fledge and ext.prebid.paaFormat = IAB"() { given: "Default basic BidRequest without ae" def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.ae = NOT_SUPPORTED + imp[0].ext.auctionEnvironment = NOT_SUPPORTED imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx ext.prebid.paaFormat = IAB } From 8d805419c3a16847c28ea081e4c49c88c057fac8 Mon Sep 17 00:00:00 2001 From: markiian Date: Wed, 15 Jan 2025 15:50:13 +0200 Subject: [PATCH 5/7] Update after review --- .../prebid/server/functional/model/request/auction/ImpExt.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy index 201858525cc..55c626d7bd6 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy @@ -23,6 +23,7 @@ class ImpExt { String tid String gpid String sid + @JsonProperty("ae") AuctionEnvironment auctionEnvironment String all String skadn From 68e2a2c6df32b0b459a602d8a28a6694a03ba60c Mon Sep 17 00:00:00 2001 From: markiian Date: Tue, 21 Jan 2025 13:44:32 +0200 Subject: [PATCH 6/7] Update after review --- .../functional/model/bidder/BidderName.groovy | 1 + .../model/request/auction/Bidder.groovy | 2 + .../model/request/auction/PaaFormat.groovy | 2 +- .../tests/bidder/openx/OpenxSpec.groovy | 296 ++++++++++++++++++ 4 files changed, 300 insertions(+), 1 deletion(-) diff --git a/src/test/groovy/org/prebid/server/functional/model/bidder/BidderName.groovy b/src/test/groovy/org/prebid/server/functional/model/bidder/BidderName.groovy index 352080844ab..54e0a451fc6 100644 --- a/src/test/groovy/org/prebid/server/functional/model/bidder/BidderName.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/bidder/BidderName.groovy @@ -18,6 +18,7 @@ enum BidderName { APPNEXUS("appnexus"), RUBICON_ALIAS("rubiconAlias"), OPENX("openx"), + OPENX_ALIAS("openxalias"), ACEEX("aceex"), ACUITYADS("acuityads"), AAX("aax"), diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/Bidder.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/Bidder.groovy index 605f286c803..05a43bbb528 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/Bidder.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/Bidder.groovy @@ -22,6 +22,8 @@ class Bidder { AppNexus appNexus Openx openx Ix ix + @JsonProperty("openxalias") + Openx openxAlias static Bidder getDefaultBidder() { new Bidder().tap { diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormat.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormat.groovy index 948f63806b1..79f41e953fe 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormat.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormat.groovy @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonValue enum PaaFormat { - ORIGINAL, IAB + ORIGINAL, IAB, INVALID @JsonValue String getValue() { diff --git a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy index cb6cbc5bd3f..8486c7d9cac 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy @@ -1,18 +1,29 @@ package org.prebid.server.functional.tests.bidder.openx +import org.prebid.server.functional.model.Currency import org.prebid.server.functional.model.bidder.Openx import org.prebid.server.functional.model.config.AccountAuctionConfig import org.prebid.server.functional.model.config.AccountConfig import org.prebid.server.functional.model.db.Account import org.prebid.server.functional.model.request.auction.BidRequest +import org.prebid.server.functional.model.request.auction.PaaFormat +import org.prebid.server.functional.model.response.auction.InterestGroupAuctionBuyer +import org.prebid.server.functional.model.response.auction.InterestGroupAuctionBuyerExt +import org.prebid.server.functional.model.response.auction.InterestGroupAuctionIntent +import org.prebid.server.functional.model.response.auction.InterestGroupAuctionSeller import org.prebid.server.functional.model.response.auction.OpenxBidResponse import org.prebid.server.functional.model.response.auction.OpenxBidResponseExt +import org.prebid.server.functional.service.PrebidServerException import org.prebid.server.functional.service.PrebidServerService import org.prebid.server.functional.tests.BaseSpec import org.prebid.server.functional.util.PBSUtils import spock.lang.Shared +import java.time.Instant + import static org.prebid.server.functional.model.bidder.BidderName.OPENX +import static org.prebid.server.functional.model.bidder.BidderName.OPENX_ALIAS +import static org.prebid.server.functional.model.bidder.BidderName.WILDCARD import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.DEVICE_ORCHESTRATED import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.NOT_SUPPORTED import static org.prebid.server.functional.model.request.auction.PaaFormat.IAB @@ -23,6 +34,8 @@ class OpenxSpec extends BaseSpec { private static final Map OPENX_CONFIG = ["adapters.openx.enabled" : "true", "adapters.openx.endpoint": "$networkServiceContainer.rootUri/auction".toString()] + private static final Map OPENX_ALIAS_CONFIG = ["adapters.openx.aliases.openxalias.enabled" : "true", + "adapters.openx.aliases.openxalias.endpoint": "$networkServiceContainer.rootUri/auction".toString()] @Shared PrebidServerService pbsService = pbsServiceFactory.getService(OPENX_CONFIG) @@ -56,6 +69,12 @@ class OpenxSpec extends BaseSpec { assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value assert auctionConfigs[0].config == fledgeConfig + + and: "PBS response shouldn't contain igb config" + assert !response.ext?.interestGroupAuctionIntent?.interestGroupAuctionBuyer + + and: "PBS response shouldn't contain igs config" + assert !response.ext?.interestGroupAuctionIntent?.interestGroupAuctionSeller } def "PBS should populate fledge config when bid response with fledge and ext.prebid.paaFormat = ORIGINAL"() { @@ -88,6 +107,12 @@ class OpenxSpec extends BaseSpec { assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value assert auctionConfigs[0].config == fledgeConfig + + and: "PBS response shouldn't contain igb config" + assert !response.ext?.interestGroupAuctionIntent?.interestGroupAuctionBuyer + + and: "PBS response shouldn't contain igs config" + assert !response.ext?.interestGroupAuctionIntent?.interestGroupAuctionSeller } def "PBS shouldn't populate fledge config when bid response with fledge and ext.prebid.paaFormat = IAB"() { @@ -114,6 +139,16 @@ class OpenxSpec extends BaseSpec { then: "PBS response shouldn't contain fledge config" assert !response.ext.prebid.fledge + + and: "PBS response shouldn't contain igb config" + assert !response.ext?.interestGroupAuctionIntent?[0]?.interestGroupAuctionBuyer + + and: "PBS response should contain igs config" + def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] + assert interestGroupAuctionSeller.impId == impId + assert interestGroupAuctionSeller.config + assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionSeller.ext.adapter == OPENX.value } def "PBS shouldn't populate fledge config when bid response didn't return fledge config"() { @@ -137,6 +172,9 @@ class OpenxSpec extends BaseSpec { then: "PBS response shouldn't contain fledge config" assert !response.ext.prebid.fledge + + and: "PBS response shouldn't contain igi config" + assert !response?.ext?.interestGroupAuctionIntent } def "PBS should populate fledge and iab output config when bid response with fledge and paa formant IAB"() { @@ -176,10 +214,268 @@ class OpenxSpec extends BaseSpec { assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value + and: "PBS response shouldn't contain igb config" + assert !response.ext?.interestGroupAuctionIntent?[0]?.interestGroupAuctionBuyer + where: accountPaaFormat | requestPaaFormant IAB | IAB null | IAB IAB | null } + + def "PBS should populate fledge config by default when bid response with fledge and requested aliases"() { + given: "PBS config with alias config" + def pbsService = pbsServiceFactory.getService(OPENX_CONFIG + OPENX_ALIAS_CONFIG) + + and: "Default basic BidRequest with ae and bidder" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.generic = null + imp[0].ext.prebid.bidder.openxAlias = Openx.defaultOpenx + ext.prebid.aliases = [(OPENX_ALIAS.value): OPENX] + } + + and: "Default bid response with fledge config" + def impId = bidRequest.imp[0].id + def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX_ALIAS).tap { + ext = new OpenxBidResponseExt().tap { + fledgeAuctionConfigs = [(impId): fledgeConfig] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response should contain fledge config" + def auctionConfigs = response.ext?.prebid?.fledge?.auctionConfigs + assert auctionConfigs?.size() == 1 + assert auctionConfigs[0].impId == impId + assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value + assert auctionConfigs[0].adapter == OPENX.value + assert auctionConfigs[0].config == fledgeConfig + + and: "PBS response shouldn't contain igi config" + assert !response.ext?.interestGroupAuctionIntent + } + + def "PBS should populate iab config when bid response with fledge and requested aliases"() { + given: "PBS config" + def pbsService = pbsServiceFactory.getService(OPENX_CONFIG + OPENX_ALIAS_CONFIG) + + and: "Default basic BidRequest with ae and openx bidder" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.generic = null + imp[0].ext.prebid.bidder.openxAlias = Openx.defaultOpenx + ext.prebid.aliases = [(OPENX_ALIAS.value): OPENX] + ext.prebid.paaFormat = IAB + } + + and: "Default bid response with fledge config" + def impId = bidRequest.imp[0].id + def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX_ALIAS).tap { + ext = new OpenxBidResponseExt().tap { + fledgeAuctionConfigs = [(impId): fledgeConfig] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response shouldn't contain fledge config" + assert !response.ext?.prebid?.fledge?.auctionConfigs + + and: "PBS response should contain igs config" + def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] + assert interestGroupAuctionSeller.impId == impId + assert interestGroupAuctionSeller.config == fledgeConfig + assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value + assert interestGroupAuctionSeller.ext.adapter == OPENX.value + + and: "PBS response shouldn't contain igi config" + assert !response.ext?.interestGroupAuctionIntent?[0].interestGroupAuctionBuyer + } + + def "PBS should populate fledge config by default when bid response with fledge and imp mismatched"() { + given: "Default basic BidRequest with ae and openx bidder" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + } + + and: "Default bid response with fledge config" + def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { + ext = new OpenxBidResponseExt().tap { + fledgeAuctionConfigs = [(fledgeImpId): fledgeConfig] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response should contain fledge config" + def auctionConfigs = response.ext?.prebid?.fledge?.auctionConfigs + assert auctionConfigs?.size() == 1 + assert auctionConfigs[0].impId == fledgeImpId + assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value + assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value + assert auctionConfigs[0].config == fledgeConfig + + and: "PBS response shouldn't contain igi config" + assert !response.ext?.interestGroupAuctionIntent + + where: + fledgeImpId << [PBSUtils.randomString, PBSUtils.randomNumber as String, WILDCARD.value] + } + + def "PBS should log error and not populated fledge impId when bidder respond with empty config"() { + given: "Start time" + def startTime = Instant.now() + + and: "Default basic BidRequest with ae and openx bidder" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + ext.prebid.paaFormat = IAB + } + + and: "Default bid response with fledge config without imp" + def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { + ext = new OpenxBidResponseExt().tap { + fledgeAuctionConfigs = [(""): fledgeConfig] as Map + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response shouldn't contain fledge config" + assert !response.ext?.prebid?.fledge?.auctionConfigs + + and: "PBS response shouldn't contain igi config" + assert !response.ext?.interestGroupAuctionIntent + + and: "PBS log should contain error" + def logs = pbsService.getLogsByTime(startTime) + assert getLogsByText(logs, "ExtIgiIgs with absent impId from bidder: ${OPENX.value}") + } + + def "PBS shouldn't populate fledge or igi config when bidder respond with igb"() { + given: "Default basic BidRequest with ae and openx bidder" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + } + + and: "Default bid response with igb config" + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { + ext = new OpenxBidResponseExt().tap { + interestGroupAuctionIntent = [new InterestGroupAuctionIntent( + interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer( + origin: PBSUtils.randomString, + maxBid: PBSUtils.randomDecimal, + cur: PBSUtils.getRandomEnum(Currency), + pbs: [(PBSUtils.randomString): PBSUtils.randomString], + ext: new InterestGroupAuctionBuyerExt( + bidder: PBSUtils.randomString, + adapter: PBSUtils.randomString + ) + )]) + ] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response should contain fledge config" + assert !response.ext?.prebid?.fledge?.auctionConfigs + + and: "PBS response shouldn't contain igi config" + assert !response.ext?.interestGroupAuctionIntent + } + + def "PBS should throw error when requested unknown paa format"() { + given: "Default basic BidRequest with ae and openx bidder" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + ext.prebid.paaFormat = PaaFormat.INVALID + } + + and: "Default bid response with fledge config" + def impId = bidRequest.imp[0].id + def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { + ext = new OpenxBidResponseExt().tap { + fledgeAuctionConfigs = [(impId): fledgeConfig] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + when: "PBS processes auction request" + pbsService.sendAuctionRequest(bidRequest) + + then: "Request should fail with error" + def exception = thrown(PrebidServerException) + assert exception.responseBody.startsWith("Invalid request format: Error decoding bidRequest: " + + "Cannot deserialize value of type `org.prebid.server.auction.model.PaaFormat` " + + "from String \"invalid\": not one of the values accepted for Enum class: [original, iab]") + } + + def "PBS shouldn't cause error when igs and igb empty array"() { + given: "Default basic BidRequest with ae and openx bidder" + def bidRequest = BidRequest.defaultBidRequest.tap { + imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED + imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx + ext.prebid.paaFormat = paaFormat + } + + and: "Default bid response with igs config" + def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { + ext = new OpenxBidResponseExt().tap { + interestGroupAuctionIntent = [new InterestGroupAuctionIntent( + interestGroupAuctionSeller: [new InterestGroupAuctionSeller()], + interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer()] + )] + } + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + when: "PBS processes auction request" + def response = pbsService.sendAuctionRequest(bidRequest) + + then: "PBS response should contain fledge config" + assert !response.ext?.prebid?.fledge?.auctionConfigs + + and: "PBS response shouldn't contain igi config" + assert !response.ext?.interestGroupAuctionIntent + + where: + paaFormat << [IAB, ORIGINAL] + } } From d81811ae4c899ff036e58290fc7510135375ae11 Mon Sep 17 00:00:00 2001 From: markiian Date: Tue, 21 Jan 2025 14:16:52 +0200 Subject: [PATCH 7/7] Update after review --- .../server/functional/tests/bidder/openx/OpenxSpec.groovy | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy index 8486c7d9cac..3e01b1ce93e 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy @@ -363,6 +363,9 @@ class OpenxSpec extends BaseSpec { and: "Set bidder response" bidder.setResponse(bidRequest.id, bidResponse) + and: "Flush metrics" + flushMetrics(pbsService) + when: "PBS processes auction request" def response = pbsService.sendAuctionRequest(bidRequest) @@ -375,6 +378,10 @@ class OpenxSpec extends BaseSpec { and: "PBS log should contain error" def logs = pbsService.getLogsByTime(startTime) assert getLogsByText(logs, "ExtIgiIgs with absent impId from bidder: ${OPENX.value}") + + and: "Alert.general metric should be updated" + def metrics = pbsService.sendCollectedMetricsRequest() + assert metrics["alerts.general" as String] == 1 } def "PBS shouldn't populate fledge or igi config when bidder respond with igb"() {