diff --git a/src/test/groovy/org/prebid/server/functional/model/config/AccountConfig.groovy b/src/test/groovy/org/prebid/server/functional/model/config/AccountConfig.groovy index 9dded674fee..83912535a57 100644 --- a/src/test/groovy/org/prebid/server/functional/model/config/AccountConfig.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/AccountConfig.groovy @@ -26,6 +26,7 @@ class AccountConfig { AlternateBidderCodes alternateBidderCodes @JsonProperty("alternate_bidder_codes") AlternateBidderCodes alternateBidderCodesSnakeCase + AccountVtrackConfig vtrack static getDefaultAccountConfig() { new AccountConfig(status: AccountStatus.ACTIVE) diff --git a/src/test/groovy/org/prebid/server/functional/model/config/AccountVtrackConfig.groovy b/src/test/groovy/org/prebid/server/functional/model/config/AccountVtrackConfig.groovy new file mode 100644 index 00000000000..77397e20b4c --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/config/AccountVtrackConfig.groovy @@ -0,0 +1,9 @@ +package org.prebid.server.functional.model.config + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class AccountVtrackConfig { + + Integer ttl +} diff --git a/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy b/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy index b9c173baa54..499f54d0272 100644 --- a/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy +++ b/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy @@ -214,7 +214,7 @@ class PrebidServerService implements ObjectMapperWrapper { } PrebidCacheResponse sendVtrackRequest(VtrackRequest request, String account) { - def response = given(requestSpecification).queryParam("a", account) + def response = given(requestSpecification).queryParams(["a": account]) .body(request) .post(VTRACK_ENDPOINT) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy index b745ae53a1f..7a36ea011c2 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy @@ -4,6 +4,7 @@ import org.prebid.server.functional.model.config.AccountAuctionConfig import org.prebid.server.functional.model.config.AccountCacheConfig import org.prebid.server.functional.model.config.AccountConfig import org.prebid.server.functional.model.config.AccountEventsConfig +import org.prebid.server.functional.model.config.AccountVtrackConfig import org.prebid.server.functional.model.db.Account import org.prebid.server.functional.model.request.auction.Asset import org.prebid.server.functional.model.request.auction.BidRequest @@ -13,8 +14,10 @@ import org.prebid.server.functional.model.request.vtrack.VtrackRequest import org.prebid.server.functional.model.request.vtrack.xml.Vast import org.prebid.server.functional.model.response.auction.Adm import org.prebid.server.functional.model.response.auction.BidResponse +import org.prebid.server.functional.service.PrebidServerException import org.prebid.server.functional.util.PBSUtils +import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST import static org.prebid.server.functional.model.response.auction.ErrorType.CACHE import static org.prebid.server.functional.model.AccountStatus.ACTIVE import static org.prebid.server.functional.model.bidder.BidderName.GENERIC @@ -607,7 +610,7 @@ class CacheSpec extends BaseSpec { assert prebidCache.getRequestCount(bidRequest.imp[0].id) == 1 and: "Bid response targeting should contain value" - verifyAll (bidResponse?.seatbid[0]?.bid[0]?.ext?.prebid?.targeting as Map) { + verifyAll(bidResponse?.seatbid[0]?.bid[0]?.ext?.prebid?.targeting as Map) { it.get("hb_cache_id") it.get("hb_cache_id_generic") it.get("hb_cache_path") == CACHE_PATH @@ -643,7 +646,7 @@ class CacheSpec extends BaseSpec { assert prebidCache.getRequestCount(bidRequest.imp[0].id) == 1 and: "Bid response targeting should contain value" - verifyAll (bidResponse.seatbid[0].bid[0].ext.prebid.targeting) { + verifyAll(bidResponse.seatbid[0].bid[0].ext.prebid.targeting) { it.get("hb_cache_id") it.get("hb_cache_id_generic") it.get("hb_cache_path") == INTERNAL_CACHE_PATH @@ -785,4 +788,119 @@ class CacheSpec extends BaseSpec { where: enabledCacheConcfig << [null, false, true] } + + def "PBS should failed VTrack request when sending request without account"() { + given: "Default VtrackRequest" + def creative = encodeXml(Vast.getDefaultVastModel(PBSUtils.randomString)) + def request = VtrackRequest.getDefaultVtrackRequest(creative) + + and: "Flush metrics" + flushMetrics(defaultPbsService) + + when: "PBS processes vtrack request" + defaultPbsService.sendVtrackRequest(request, null) + + then: "Request should fail with an error" + def exception = thrown(PrebidServerException) + assert exception.statusCode == BAD_REQUEST.code() + assert exception.responseBody == "Account 'a' is required query parameter and can't be empty" + } + + def "PBS shouldn't use negative value in tllSecond when account vtrack ttl is #accountTtl and request ttl second is #requestedTtl"() { + given: "Default VtrackRequest" + def creative = encodeXml(Vast.getDefaultVastModel(PBSUtils.randomString)) + def request = VtrackRequest.getDefaultVtrackRequest(creative).tap { + puts[0].ttlseconds = requestedTtl + } + + and: "Create and save vtrack in account" + def accountId = PBSUtils.randomNumber.toString() + def account = new Account().tap { + it.uuid = accountId + it.config = new AccountConfig().tap { + it.vtrack = new AccountVtrackConfig(ttl: accountTtl) + } + } + accountDao.save(account) + + and: "Flush metrics" + flushMetrics(defaultPbsService) + + when: "PBS processes vtrack request" + defaultPbsService.sendVtrackRequest(request, accountId) + + then: "Pbs should emit creative_ttl.xml with lowest value" + def metrics = defaultPbsService.sendCollectedMetricsRequest() + assert metrics[XML_CREATIVE_TTL_ACCOUNT_METRIC.formatted(accountId)] + == [requestedTtl, accountTtl].findAll { it -> it > 0 }.min() + + where: + requestedTtl | accountTtl + PBSUtils.getRandomNumber(300, 1500) as Integer | PBSUtils.getRandomNegativeNumber(-1500, 300) as Integer + PBSUtils.getRandomNegativeNumber(-1500, 300) as Integer | PBSUtils.getRandomNumber(300, 1500) as Integer + PBSUtils.getRandomNegativeNumber(-1500, 300) as Integer | PBSUtils.getRandomNegativeNumber(-1500, 300) as Integer + } + + def "PBS should use lowest tllSecond when account vtrack ttl is #accountTtl and request ttl second is #requestedTtl"() { + given: "Default VtrackRequest" + def creative = encodeXml(Vast.getDefaultVastModel(PBSUtils.randomString)) + def request = VtrackRequest.getDefaultVtrackRequest(creative).tap { + puts[0].ttlseconds = requestedTtl + } + + and: "Create and save vtrack in account" + def accountId = PBSUtils.randomNumber.toString() + def account = new Account().tap { + it.uuid = accountId + it.config = new AccountConfig().tap { + it.vtrack = new AccountVtrackConfig(ttl: accountTtl) + } + } + accountDao.save(account) + + and: "Flush metrics" + flushMetrics(defaultPbsService) + + when: "PBS processes vtrack request" + defaultPbsService.sendVtrackRequest(request, accountId) + + then: "Pbs should emit creative_ttl.xml with lowest value" + def metrics = defaultPbsService.sendCollectedMetricsRequest() + assert metrics[XML_CREATIVE_TTL_ACCOUNT_METRIC.formatted(accountId)] == [requestedTtl, accountTtl].min() + + where: + requestedTtl | accountTtl + null | null + null | PBSUtils.getRandomNumber(300, 1500) as Integer + PBSUtils.getRandomNumber(300, 1500) as Integer | null + PBSUtils.getRandomNumber(300, 1500) as Integer | PBSUtils.getRandomNumber(300, 1500) as Integer + } + + def "PBS should proceed request when account ttl and request ttl second are empty"() { + given: "Default VtrackRequest" + def creative = encodeXml(Vast.getDefaultVastModel(PBSUtils.randomString)) + def request = VtrackRequest.getDefaultVtrackRequest(creative).tap { + puts[0].ttlseconds = null + } + + and: "Create and save vtrack in account" + def accountId = PBSUtils.randomNumber.toString() + def account = new Account().tap { + it.uuid = accountId + it.config = new AccountConfig().tap { + it.vtrack = new AccountVtrackConfig(ttl: null) + } + } + accountDao.save(account) + + and: "Flush metrics" + flushMetrics(defaultPbsService) + + when: "PBS processes vtrack request" + defaultPbsService.sendVtrackRequest(request, accountId) + + then: "Pbs shouldn't emit creative_ttl.xml" + def metrics = defaultPbsService.sendCollectedMetricsRequest() + assert !metrics[XML_CREATIVE_TTL_ACCOUNT_METRIC.formatted(accountId)] + } }