From 6c963ff540d7ca5a8b626b83d62e5a4f42cfca6e Mon Sep 17 00:00:00 2001 From: markiian Date: Thu, 10 Aug 2023 13:11:29 +0300 Subject: [PATCH 01/16] Increase tests coverage for cookie sync endpoint --- .../functional/model/bidder/BidderName.groovy | 2 +- .../vendorlist/VendorListResponse.groovy | 9 +- .../request/cookiesync/MethodFilter.groovy | 6 +- .../service/PrebidServerService.groovy | 19 +- .../scaffolding/VendorList.groovy | 6 +- .../functional/tests/CookieSyncSpec.groovy | 845 +++++++++++++++++- .../server/functional/tests/SetUidSpec.groovy | 2 - .../tests/privacy/GdprAmpSpec.groovy | 8 +- .../tests/privacy/GdprAuctionSpec.groovy | 14 +- .../tests/privacy/GppAuctionSpec.groovy | 2 +- .../tests/privacy/GppCookieSyncSpec.groovy | 2 +- .../functional/util/privacy/TcfConsent.groovy | 11 +- 12 files changed, 877 insertions(+), 49 deletions(-) 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 5c7fc6f123e..4419a4628ef 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 @@ -5,7 +5,7 @@ import net.minidev.json.annotate.JsonIgnore enum BidderName { - ALIAS, GENERIC, RUBICON, APPNEXUS, BOGUS, OPENX + ALIAS, GENERIC, RUBICON, APPNEXUS, BOGUS, OPENX, ACEEX, ACUITYADS, GRID, AAX, ADKERNEL, MEDIANET @JsonValue String getValue() { diff --git a/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy b/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy index 50b80791d6d..84f569599ab 100644 --- a/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy @@ -1,12 +1,12 @@ package org.prebid.server.functional.model.mock.services.vendorlist import org.prebid.server.functional.util.PBSUtils -import org.prebid.server.functional.util.privacy.TcfConsent import java.time.Clock import java.time.ZonedDateTime import static org.prebid.server.functional.util.privacy.TcfConsent.GENERIC_VENDOR_ID +import static org.prebid.server.functional.util.privacy.TcfConsent.VENDOR_RUBICON_ID class VendorListResponse { @@ -21,7 +21,8 @@ class VendorListResponse { it.gvlSpecificationVersion = 2 it.tcfPolicyVersion = 2 it.lastUpdated = ZonedDateTime.now(Clock.systemUTC()).minusWeeks(2) - it.vendors = [(GENERIC_VENDOR_ID): Vendor.defaultVendor] + it.vendors = [(GENERIC_VENDOR_ID): Vendor.getDefaultVendor(GENERIC_VENDOR_ID), + (VENDOR_RUBICON_ID): Vendor.getDefaultVendor(VENDOR_RUBICON_ID)] } } @@ -43,9 +44,9 @@ class VendorListResponse { Boolean usesNonCookieAccess Boolean deviceStorageDisclosureUrl - static Vendor getDefaultVendor() { + static Vendor getDefaultVendor(Integer id) { new Vendor().tap { - it.id = GENERIC_VENDOR_ID + it.id = id it.name = PBSUtils.randomString it.purposes = [1, 3, 4, 5] it.legIntPurposes = [2, 7, 10] diff --git a/src/test/groovy/org/prebid/server/functional/model/request/cookiesync/MethodFilter.groovy b/src/test/groovy/org/prebid/server/functional/model/request/cookiesync/MethodFilter.groovy index 1e756173fa7..0a74beaecb6 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/cookiesync/MethodFilter.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/cookiesync/MethodFilter.groovy @@ -1,11 +1,11 @@ package org.prebid.server.functional.model.request.cookiesync import groovy.transform.ToString -import org.prebid.server.functional.model.bidder.BidderName @ToString(includeNames = true, ignoreNulls = true) -class MethodFilter { +class MethodFilter { - List bidders + // Here we use wildcard for different compatibility + T bidders FilterType filter } 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 da761eb639b..58bee588be0 100644 --- a/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy +++ b/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy @@ -119,7 +119,7 @@ class PrebidServerService implements ObjectMapperWrapper { @Step("[POST] /cookie_sync without cookie") CookieSyncResponse sendCookieSyncRequest(CookieSyncRequest request) { - def response = postCookieSync(request) + def response = postCookieSync(request, null) checkResponseStatusCode(response) response.as(CookieSyncResponse) @@ -135,7 +135,15 @@ class PrebidServerService implements ObjectMapperWrapper { @Step("[POST] /cookie_sync with uids cookie") CookieSyncResponse sendCookieSyncRequest(CookieSyncRequest request, UidsCookie uidsCookie) { - def response = postCookieSync(request, uidsCookie) + def response = postCookieSync(request, uidsCookie, null) + + checkResponseStatusCode(response) + response.as(CookieSyncResponse) + } + + @Step("[POST] /cookie_sync with uids cookie") + CookieSyncResponse sendCookieSyncRequest(CookieSyncRequest request, String uidsCookie) { + def response = postCookieSync(request, null, null, null, uidsCookie) checkResponseStatusCode(response) response.as(CookieSyncResponse) @@ -317,7 +325,8 @@ class PrebidServerService implements ObjectMapperWrapper { private Response postCookieSync(CookieSyncRequest cookieSyncRequest, UidsCookie uidsCookie = null, Map additionalCookies = null, - Map header = null) { + Map header = null, + String uidsAudit = null) { def cookies = [:] @@ -329,6 +338,10 @@ class PrebidServerService implements ObjectMapperWrapper { cookies.put(UIDS_COOKIE_NAME, Base64.urlEncoder.encodeToString(encode(uidsCookie).bytes)) } + if (uidsAudit) { + cookies.put("uids-audit", uidsAudit) + } + postCookieSync(cookieSyncRequest, cookies, header) } diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy index 184f9393761..9c1782bfacd 100644 --- a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy @@ -11,6 +11,7 @@ import static org.mockserver.model.HttpRequest.request import static org.mockserver.model.HttpResponse.response import static org.mockserver.model.HttpStatusCode.OK_200 import static org.prebid.server.functional.util.privacy.TcfConsent.TcfPolicyVersion +import static org.prebid.server.functional.util.privacy.TcfConsent.TcfPolicyVersion.TCF_POLICY_V2 class VendorList extends NetworkScaffolding { @@ -30,10 +31,7 @@ class VendorList extends NetworkScaffolding { request().withPath(VENDOR_LIST_ENDPOINT) } - @Override - void setResponse(){} - - void setResponse(TcfPolicyVersion tcfPolicyVersion) { + void setResponse(TcfPolicyVersion tcfPolicyVersion = TCF_POLICY_V2) { def prepareEndpoint = endpoint.replace("{TCF_POLICY}", "v" + tcfPolicyVersion.vendorListVersion) def prepareEncodeResponseBody = encode(VendorListResponse.defaultVendorListResponse.tap { it.vendorListVersion = tcfPolicyVersion.vendorListVersion diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index 2eb08e7c3d4..bab6e1606e5 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -15,6 +15,7 @@ import org.prebid.server.functional.model.request.cookiesync.MethodFilter import org.prebid.server.functional.model.response.cookiesync.CookieSyncResponse import org.prebid.server.functional.model.response.cookiesync.UserSyncInfo import org.prebid.server.functional.service.PrebidServerService +import org.prebid.server.functional.testcontainers.scaffolding.VendorList import org.prebid.server.functional.util.HttpUtil import org.prebid.server.functional.util.PBSUtils import org.prebid.server.functional.util.privacy.CcpaConsent @@ -22,14 +23,23 @@ import org.prebid.server.functional.util.privacy.TcfConsent import java.time.Instant +import static org.prebid.server.functional.model.bidder.BidderName.ACEEX +import static org.prebid.server.functional.model.bidder.BidderName.ACUITYADS +import static org.prebid.server.functional.model.bidder.BidderName.ADKERNEL import static org.prebid.server.functional.model.bidder.BidderName.ALIAS import static org.prebid.server.functional.model.bidder.BidderName.APPNEXUS +import static org.prebid.server.functional.model.bidder.BidderName.AAX import static org.prebid.server.functional.model.bidder.BidderName.BOGUS import static org.prebid.server.functional.model.bidder.BidderName.GENERIC +import static org.prebid.server.functional.model.bidder.BidderName.OPENX import static org.prebid.server.functional.model.bidder.BidderName.RUBICON import static org.prebid.server.functional.model.request.cookiesync.FilterType.EXCLUDE +import static org.prebid.server.functional.model.request.cookiesync.FilterType.INCLUDE import static org.prebid.server.functional.model.response.cookiesync.CookieSyncResponse.Status.NO_COOKIE import static org.prebid.server.functional.model.response.cookiesync.CookieSyncResponse.Status.OK +import static org.prebid.server.functional.model.response.cookiesync.UserSyncInfo.Format.BLANK +import static org.prebid.server.functional.model.response.cookiesync.UserSyncInfo.Format.PIXEL +import static org.prebid.server.functional.model.response.cookiesync.UserSyncInfo.Type.IFRAME import static org.prebid.server.functional.model.response.cookiesync.UserSyncInfo.Type.REDIRECT import static org.prebid.server.functional.testcontainers.Dependencies.networkServiceContainer import static org.prebid.server.functional.util.privacy.CcpaConsent.Signal.ENFORCED @@ -41,18 +51,51 @@ class CookieSyncSpec extends BaseSpec { private static final UserSyncInfo.Type USER_SYNC_TYPE = REDIRECT private static final boolean CORS_SUPPORT = false private static final String USER_SYNC_URL = "$networkServiceContainer.rootUri/generic-usersync" + private static final Map GDPR_VENDOR_LIST_CONFIG = ["gdpr.vendorlist.v2.http-endpoint-template": "$networkServiceContainer.rootUri/v2/vendor-list.json".toString(), + "gdpr.vendorlist.v3.http-endpoint-template": "$networkServiceContainer.rootUri/v3/vendor-list.json".toString()] private static final Map GENERIC_CONFIG = [ - "adapters.${GENERIC.value}.usersync.${USER_SYNC_TYPE.value}.url" : USER_SYNC_URL, - "adapters.${GENERIC.value}.usersync.${USER_SYNC_TYPE.value}.support-cors": CORS_SUPPORT.toString()] + "adapters.${GENERIC.value}.usersync.redirect.url" : USER_SYNC_URL, + "adapters.${GENERIC.value}.usersync.redirect.support-cors": "false", + "adapters.${GENERIC.value}.meta-info.vendor-id" : GENERIC_VENDOR_ID as String] + private static final Map ACEEX_CONFIG = [ + "adapters.${ACEEX.value}.enabled" : "true", + "adapters.${ACEEX.value}.usersync.cookie-family-name" : ACEEX.value, + "adapters.${ACEEX.value}.usersync.redirect.url" : "https://test.redirect.endpoint.com={{redirect_url}}", + "adapters.${ACEEX.value}.usersync.redirect.support-cors": "false"] private static final Map RUBICON_CONFIG = [ - "adapters.${RUBICON.value}.enabled" : "true", - "adapters.${RUBICON.value}.usersync.cookie-family-name": RUBICON.value,] + "adapters.${RUBICON.value}.enabled" : "true", + "adapters.${RUBICON.value}.meta-info.vendor-id" : 33 as String, + "adapters.${RUBICON.value}.usersync.cookie-family-name" : RUBICON.value, + "adapters.${RUBICON.value}.usersync.redirect.url" : "https://test.redirect.endpoint.com", + "adapters.${RUBICON.value}.usersync.redirect.support-cors": "false", + "adapters.${RUBICON.value}.usersync.iframe.url" : "https://test.iframe.endpoint.com&redir={{redirect_url}}", + "adapters.${RUBICON.value}.usersync.iframe.support-cors" : "false"] + private static final Map OPENX_CONFIG = [ + "adapters.${OPENX.value}.enabled" : "true", + "adapters.${OPENX.value}.usersync.cookie-family-name" : OPENX.value, + "adapters.${OPENX.value}.usersync.redirect.url" : USER_SYNC_URL, + "adapters.${OPENX.value}.usersync.redirect.support-cors": "false", + "adapters.${OPENX.value}.usersync.iframe.url" : USER_SYNC_URL, + "adapters.${OPENX.value}.usersync.iframe.support-cors" : "false"] private static final Map APPNEXUS_CONFIG = [ - "adapters.${APPNEXUS.value}.enabled" : "true", - "adapters.${APPNEXUS.value}.usersync.cookie-family-name": APPNEXUS.value] - private static final Map PBS_CONFIG = APPNEXUS_CONFIG + RUBICON_CONFIG + GENERIC_CONFIG - - private PrebidServerService prebidServerService = pbsServiceFactory.getService(PBS_CONFIG) + "adapters.${APPNEXUS.value}.enabled" : "true", + "adapters.${APPNEXUS.value}.usersync.cookie-family-name" : APPNEXUS.value, + "adapters.${APPNEXUS.value}.usersync.redirect.url" : "https://test.appnexus.redirect.com/getuid?{{redirect_url}}", + "adapters.${APPNEXUS.value}.usersync.redirect.support-cors": "false", + "adapters.${APPNEXUS.value}.usersync.iframe.url" : "https://test.iframe.endpoint.com", + "adapters.${APPNEXUS.value}.usersync.iframe.support-cors" : "false"] + private static final Map AAX_CONFIG = ["adapters.${AAX.value}.enabled": "true"] + private static final Map ACUITYADS_CONFIG = ["adapters.${ACUITYADS.value}.enabled": "true"] + private static final Map ADKERNEL_CONFIG = ["adapters.${ADKERNEL.value}.enabled": "true"] + + private static final Map PBS_CONFIG = APPNEXUS_CONFIG + RUBICON_CONFIG + OPENX_CONFIG + + GENERIC_CONFIG + ACEEX_CONFIG + AAX_CONFIG + ACUITYADS_CONFIG + ADKERNEL_CONFIG + + GDPR_VENDOR_LIST_CONFIG + ["cookie-sync.pri": "grid, ix, adkernel"] + + private final PrebidServerService prebidServerService = pbsServiceFactory.getService(PBS_CONFIG) + private final VendorList vendorListResponse = new VendorList(networkServiceContainer).tap { + setResponse() + } def "PBS cookie sync request should replace synced as family bidder and fill up response with enabled bidders to the limit in request"() { given: "PBS config with alias bidder without cookie family name" @@ -270,7 +313,7 @@ class CookieSyncSpec extends BaseSpec { given: "Valid consent string" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() and: "Cookie sync request with gdpr and gdprConsent" @@ -603,7 +646,6 @@ class CookieSyncSpec extends BaseSpec { then: "Response should contain all 3 enabled bidders" assert response.bidderStatus.size() == countOfEnabledBidders - assert response.bidderStatus*.bidder.sort() == [RUBICON, APPNEXUS, GENERIC].sort() } def "PBS cookie sync request with alias bidder should sync as the source bidder when alias doesn't override cookie-family-name"() { @@ -611,7 +653,7 @@ class CookieSyncSpec extends BaseSpec { def bidderAlias = ALIAS def prebidServerService = pbsServiceFactory.getService(PBS_CONFIG + ["adapters.${GENERIC.value}.aliases.${bidderAlias.value}.enabled" : "true", - "adapters.${GENERIC.value}.aliases.${bidderAlias.value}.usersync.cookie-family-name": null,]) + "adapters.${GENERIC.value}.aliases.${bidderAlias.value}.usersync.cookie-family-name": null]) and: "Cookie sync request with 2 bidders" def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { @@ -1275,7 +1317,7 @@ class CookieSyncSpec extends BaseSpec { given: "Valid consent string" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() and: "Cookie sync request with gdpr and gdprConsent" @@ -1369,13 +1411,786 @@ class CookieSyncSpec extends BaseSpec { assert !response.getBidderUserSync(GENERIC) } - Map getValidBidderUserSyncs(CookieSyncResponse cookieSyncResponse) { + def "PBS cookie sync request should successful pass when request body empty"() { + given: "Empty cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest() + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response should contain '#formatParam' format parameter" + def genericBidderStatus = response.getBidderUserSync(ACEEX) + assert genericBidderStatus?.userSync?.type == REDIRECT + assert HttpUtil.findUrlParameterValue(genericBidderStatus.userSync?.url, "f") == PIXEL.name + + and: "Response should contain '#formatParam' format parameter" + def rubiconBidderStatus = response.getBidderUserSync(RUBICON) + assert rubiconBidderStatus?.userSync?.type == IFRAME + assert HttpUtil.findUrlParameterValue(rubiconBidderStatus.userSync?.url, "f") == BLANK.name + + and: "Response should contain coop-synced bidder" + assert response.bidderStatus.bidder.containsAll(ADKERNEL, ACUITYADS, ACEEX, APPNEXUS, AAX, RUBICON, OPENX, GENERIC) + } + + def "PBS cookie sync request should filter bidder due to filterSettings"() { + given: "Empty cookie sync request body" + def filterSettings = new FilterSettings().tap { + iframe = new MethodFilter().tap { + filter = INCLUDE + bidders = [RUBICON, GENERIC] + } + image = new MethodFilter().tap { + filter = EXCLUDE + bidders = [APPNEXUS, OPENX] + } + } + def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Bidder should be exclude by filter" + def rubiconUserSync = response.getBidderUserSync(RUBICON) + assert rubiconUserSync?.userSync?.type == IFRAME + + and: "Bidder shouldn't be include by filter" + assert !response.getBidderUserSync(APPNEXUS) + } + + def "PBS cookie sync request should include all bidder due to filterSettings"() { + given: "Empty cookie sync request body" + def filterSettings = new FilterSettings().tap { + iframe = new MethodFilter(bidders: [RUBICON], filter: INCLUDE) + image = new MethodFilter(bidders: [APPNEXUS], filter: INCLUDE) + } + def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Bidder should be include by filter" + assert response.getBidderUserSync(APPNEXUS) + assert response.getBidderUserSync(RUBICON) + } + + def "PBS cookie sync request should exclude all iframe bidders when asterisk present in bidders filterSettings"() { + given: "Empty cookie sync request body" + def filterSettings = new FilterSettings().tap { + iframe = new MethodFilter(bidders: "*", filter: EXCLUDE) + } + def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response shouldn't contains bidders with IFRAME" + assert response?.bidderStatus?.every { it.getUserSync().type != IFRAME } + + and: "Response should contain only bidders with IMAGE" + assert response?.bidderStatus?.every { it.getUserSync().type == REDIRECT } + } + + def "PBS cookie sync request should exclude all image bidders when asterisk present in bidders filterSettings"() { + given: "Empty cookie sync request body" + def filterSettings = new FilterSettings().tap { + image = new MethodFilter(bidders: "*", filter: EXCLUDE) + } + def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response should contains all bidders with IFRAME" + assert response?.bidderStatus?.every { it.getUserSync().type == IFRAME } + + and: "Response shouldn't contain bidders with IMAGE" + assert response?.bidderStatus?.every { it.getUserSync().type != REDIRECT } + } + + def "PBS cookie sync request shouldn't include bidder with invalid user sync type"() { + given: "Empty cookie sync request body" + def filterSettings = new FilterSettings().tap { + iframe = new MethodFilter(bidders: [GENERIC], filter: INCLUDE) + } + def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response should contain bidders with Redirect type" + def userSync = response.getBidderUserSync(GENERIC) + assert userSync?.userSync?.type == REDIRECT + } + + def "PBS cookie sync request shouldn't exclude bidder with invalid user sync type"() { + given: "Empty cookie sync request body" + def filterSettings = new FilterSettings().tap { + iframe = new MethodFilter(bidders: [GENERIC], filter: EXCLUDE) + } + def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response should contain bidders with Redirect type" + def userSync = response.getBidderUserSync(GENERIC) + assert userSync?.userSync?.type == REDIRECT + } + + def "PBS cookie sync request should ignore iframe invalid bidder in method filter bidders"() { + given: "Empty cookie sync request body" + def filterSettings = new FilterSettings().tap { + iframe = new MethodFilter(bidders: [bidders], filter: INCLUDE) + } + def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response shouldn't contain invalid bidders" + assert !response.getBidderUserSync(bidders) + + where: + bidders << [BOGUS, null] + } + + def "PBS cookie sync request should ignore image invalid bidder in method filter bidders"() { + given: "Empty cookie sync request body" + def filterSettings = new FilterSettings().tap { + image = new MethodFilter(bidders: [bidders], filter: INCLUDE) + } + def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response shouldn't contain invalid bidders" + assert !response.getBidderUserSync(bidders) + + where: + bidders << [BOGUS, null] + } + + def "PBS cookie sync request should successfully passed when account is absent"() { + given: "Empty cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest(account: null) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response should contain configured bidders" + assert response?.getBidderStatus()?.bidder?.sort() == + [GENERIC, RUBICON, APPNEXUS, OPENX, ACEEX, ACUITYADS, AAX, ADKERNEL].sort() + } + + def "PBS cookie sync request should return url for all bidders when no uids cookie is present"() { + given: "Empty cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest(account: null) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response should contain info for all configured bidder" + def bidderStatus = response?.bidderStatus?.userSync + assert bidderStatus?.url + assert bidderStatus?.type + assert bidderStatus?.supportCORS?.every(it -> it == false) + } + + def "PBS cookie sync request shouldn't return sync url when active uids cookie is present for bidder"() { + given: "Empty cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest() + + and: "Set up uids cookie" + def uidsCookie = UidsCookie.defaultUidsCookie + + when: "PBS processes cookie sync request with uids cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest, uidsCookie) + + then: "Response should have status 'OK'" + assert response.status == OK + + and: "Response shouldn't contain bidder" + assert !response?.getBidderUserSync(GENERIC) + + and: "Response should contain configured bidders" + assert response?.getBidderStatus()?.bidder?.sort() == + [RUBICON, APPNEXUS, OPENX, ACEEX, ACUITYADS, AAX, ADKERNEL].sort() + } + + def "PBS cookie sync request shouldn't return iframe sync url included by sync type bidders for bidder in cookie"() { + given: "Empty cookie sync request body" + def filterSettings = new FilterSettings().tap { + iframe = new MethodFilter(bidders: [GENERIC], filter: INCLUDE) + } + def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) + + when: "PBS processes cookie sync request with generic uid cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest, UidsCookie.defaultUidsCookie) + + then: "Response should have status 'OK'" + assert response.status == OK + + and: "Response shouldn't contain generic bidder" + assert !response.getBidderUserSync(GENERIC) + } + + def "PBS cookie sync request shouldn't return image sync url included by sync type bidders for bidder in cookie"() { + given: "Empty cookie sync request body" + def filterSettings = new FilterSettings().tap { + image = new MethodFilter(bidders: [APPNEXUS], filter: INCLUDE) + } + def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) + + and: "Set up appnexus uids cookie" + def uidsCookie = UidsCookie.getDefaultUidsCookie(APPNEXUS) + + when: "PBS processes cookie sync request with generic uid cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest, uidsCookie) + + then: "Response should have status 'OK'" + assert response.status == OK + + and: "Response shouldn't contain generic bidder" + assert !response.getBidderUserSync(APPNEXUS) + } + + def "PBS cookie sync request shouldn't return requested bidder when bidders present in uids cookie"() { + given: "Empty cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest(bidders: [GENERIC]) + + and: "Set up generic uids cookie" + def uidsCookie = UidsCookie.defaultUidsCookie + + when: "PBS processes cookie sync request with generic uid cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest, uidsCookie) + + then: "Response should have status 'OK'" + assert response.status == OK + + and: "Response shouldn't contain generic bidder" + assert !response.getBidderUserSync(GENERIC) + } + + def "PBS cookie sync request should return all possible bidder"() { + given: "Empty cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest(bidders: null, coopSync: true) + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response should contain coop sync bidder" + assert response.getBidderUserSync(AAX) + assert response.getBidderUserSync(ACUITYADS) + assert response.getBidderUserSync(ADKERNEL) + } + + def "PBS cookie sync request should contain request bidders and rest from coop sync"() { + given: "PBS config with expanded limit" + def defaultSyncLimit = 3 + def prebidServerService = pbsServiceFactory.getService( + ["cookie-sync.default-limit": defaultSyncLimit as String] + PBS_CONFIG) + + and: "Default cookie sync request" + def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { + bidders = [APPNEXUS, GENERIC] + coopSync = true + } + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + then: "Response should contain requested bidder and coop-synced" + assert response.getBidderStatus().size() > cookieSyncRequest.bidders.size() + assert response.getBidderUserSync(APPNEXUS) + assert response.getBidderUserSync(GENERIC) + } + + def "PBS cookie sync request should contain only request bidders when coop sync off"() { + given: "PBS config with expanded limit" + def defaultSyncLimit = 3 + def prebidServerService = pbsServiceFactory.getService( + ["cookie-sync.default-limit": defaultSyncLimit as String] + PBS_CONFIG) + + and: "Default cookie sync request" + def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { + bidders = [APPNEXUS, GENERIC] + coopSync = false + } + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + then: "Response should contain requested bidder and coop-synced" + assert response.getBidderStatus().size() == cookieSyncRequest.bidders.size() + assert response.getBidderUserSync(APPNEXUS) + assert response.getBidderUserSync(GENERIC) + } + + def "PBS cookie sync request should contain only request bidders with limit when coop sync off and limit specified"() { + given: "Default cookie sync request" + def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { + bidders = [APPNEXUS, GENERIC, RUBICON] + coopSync = false + limit = 2 + } + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response should contain requested bidder limit" + def rejectedBidderUserSyncs = getRejectedBidderUserSyncs(response) + assert rejectedBidderUserSyncs.size() == cookieSyncRequest.bidders.size() - cookieSyncRequest.limit + assert rejectedBidderUserSyncs.every { it.value == "limit reached" } + } + + def "PBS cookie sync request should return only requested bidder and reduce image list by filter settings"() { + given: "Default cookie sync request" + def cookieSyncRequest = new CookieSyncRequest().tap { + bidders = [RUBICON, APPNEXUS, ACEEX] + coopSync = false + filterSettings = new FilterSettings().tap { + image = new MethodFilter(bidders: [ACEEX], filter: EXCLUDE) + iframe = new MethodFilter(bidders: [RUBICON], filter: INCLUDE) + } + } + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response should contain two requested bidders" + assert response.getBidderStatus().size() == cookieSyncRequest.bidders.size() - 1 + assert response.getBidderUserSync(RUBICON) + assert response.getBidderUserSync(APPNEXUS) + + and: "Response shouldn't contain requested bidders due to filter" + assert !response.getBidderUserSync(ACEEX) + } + + def "PBS cookie sync request shouldn't return any bidder when coop sync off and bidder is invalid"() { + given: "Empty cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest(coopSync: false, bidders: givenBidder) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response shouldn't contain proper" + assert response.getBidderStatus().size() == 0 + + where: + givenBidder << [[BOGUS], []] + } + + def "PBS cookie sync request shouldn't return all bidders when coop sync #coopSync and limit param specified"() { + given: "Empty cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest(coopSync: coopSync, bidders: [APPNEXUS, RUBICON], limit: 1) + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response shouldn't contain proper" + assert response.getBidderStatus().size() == cookieSyncRequest.limit + + where: + coopSync << [true, false] + } + + def "PBS cookie sync request shouldn't increase amount of bidder then define in request"() { + given: "Empty cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest().tap { + limit = 1 + bidders = [RUBICON, GENERIC] + filterSettings = new FilterSettings(image: new MethodFilter(bidders: [RUBICON, GENERIC], filter: INCLUDE)) + } + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response shouldn't contain proper" + assert response.getBidderStatus().size() == cookieSyncRequest.limit + } + + def "PBS cookie sync request should return all users sync bidders when limit is null"() { + given: "Empty cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest().tap { + limit = null + bidders = null + } + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert response.status == NO_COOKIE + + and: "Response should contain configured bidders" + assert response?.getBidderStatus()?.size() == 8 + } + + def "PBS cookie sync request should limit the number of returned bidders"() { + given: "Cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest().tap { + it.limit = PBSUtils.getRandomNumber(1, 3) + it.coopSync = true + } + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status" + assert response.getBidderStatus().size() == cookieSyncRequest.limit + } + + def "PBS cookie sync request should return randomized bidder list"() { + given: "Cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest().tap { + it.limit = 2 + it.coopSync = coopSync + it.bidders = [GENERIC, RUBICON, APPNEXUS, ACEEX, OPENX] + } + + when: "PBS processes cookie sync request without cookies" + def firstResponse = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + def secondResponse = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should have status 'NO_COOKIE'" + assert firstResponse.bidderStatus.bidder != secondResponse.bidderStatus.bidder + + where: + coopSync << [true, false] + } + + def "PBS cookie sync request should return bidders matched in bidders and filter settings"() { + given: "Cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest().tap { + it.coopSync = false + it.bidders = [GENERIC, RUBICON] + it.filterSettings = new FilterSettings(image: new MethodFilter(bidders: [GENERIC, RUBICON, APPNEXUS], filter: INCLUDE)) + } + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should contains the same size" + assert response.bidderStatus.bidder.size() == cookieSyncRequest.bidders.size() + + and: "" + assert response.bidderStatus.bidder.containsAll(GENERIC, RUBICON) + } + + def "PBS cookie sync request should return maximum 8 coop sync bidder when limit is not specified"() { + given: "Cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest().tap { + it.coopSync = true + it.limit = null + } + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should contains 8 coop sync bidders" + assert response.bidderStatus.bidder.size() == 8 + } + + def "PBS cookie sync request should override general configuration limit"() { + given: "Cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest().tap { + it.coopSync = true + it.limit = 4 + } + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should contains 4 coop sync bidders" + assert response.bidderStatus.bidder.size() == cookieSyncRequest.limit + } + + def "PBS cookie sync request should return bidders without excluded by filter settings"() { + given: "Cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest().tap { + coopSync = false + bidders = [ACEEX, RUBICON] + filterSettings = new FilterSettings(image: new MethodFilter(bidders: [ACEEX], filter: EXCLUDE)) + debug = true + } + + when: "PBS processes cookie sync request without cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should contain error" + def bidderStatus = response.getBidderUserSync(ACEEX) + assert bidderStatus.error == "Rejected by request filter" + + and: "Response should contain one valid bidder" + assert response.getBidderUserSync(RUBICON) + } + + def "PBS cookie sync request shouldn't include bidder if this bidder in uids cookie"() { + given: "Cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest().tap { + coopSync = false + bidders = [APPNEXUS, RUBICON] + filterSettings = new FilterSettings(image: new MethodFilter(bidders: [APPNEXUS, RUBICON], filter: INCLUDE)) + debug = false + } + + and: "Given uid cookie" + def cookie = UidsCookie.getDefaultUidsCookie(APPNEXUS) + + when: "PBS processes cookie sync request with cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest, cookie) + + then: "Response should contain error" + assert response.getBidderUserSync(RUBICON) + } + + def "PBS cookie sync request should ignore uids audit cookie outside of gdpr"() { + given: "Cookie sync request body" + def cookieSyncRequest = new CookieSyncRequest().tap { + bidders = [APPNEXUS] + coopSync = false + gdpr = 0 + } + + when: "PBS processes cookie sync request with cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest, "GzhqHDTACWuj-m1FXJic6E0Vp8brrzoQDFmowPV1LQu3B5VuyOoHmyKnfRjnh-pZeKwfXVaa7TzbxxSsbYLFODxiWQptNHFKQhSTwHW5jeNbQ18Im3wwdxsPI_5nkH5zsIrfi9WP57D_6Sg23EnYeg3kBJXMAZVdb_RA8ie7ubjfC_0PMVTtZqs-Kcul81yp") + + then: "Response should contain error" + assert response.getBidderUserSync(APPNEXUS) + } + + def "PBS cookie sync request shouldn't limit bidders with zero value in config"() { + given: "Default cookie sync request" + def accountId = PBSUtils.randomNumber + def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { + bidders = [GENERIC, BOGUS] + account = accountId + } + + and: "Save account with cookie config" + def cookieSyncConfig = new AccountCookieSyncConfig(defaultLimit: 0) + def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) + def account = new Account(uuid: accountId, config: accountConfig) + accountDao.save(account) + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should contain valid bidder status" + assert response.bidderStatus.size() == 2 + } + + def "PBS cookie sync request should max limit override default limit"() { + given: "Default cookie sync request" + def accountId = PBSUtils.randomNumber + def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { + bidders = [GENERIC, BOGUS] + account = accountId + debug = false + } + + and: "Save account with cookie config" + def cookieSyncConfig = new AccountCookieSyncConfig(maxLimit: 1, defaultLimit: 2) + def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) + def account = new Account(uuid: accountId, config: accountConfig) + accountDao.save(account) + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should contain corresponding bidders size due to config" + assert response.bidderStatus.size() == 1 + } + + def "PBS cookie sync request should max limit in account take precedence over request limit"() { + given: "Default cookie sync request" + def accountId = PBSUtils.randomNumber + def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { + bidders = [GENERIC, BOGUS] + account = accountId + limit = 2 + debug = false + } + + and: "Save account with cookie config" + def cookieSyncConfig = new AccountCookieSyncConfig(maxLimit: 1) + def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) + def account = new Account(uuid: accountId, config: accountConfig) + accountDao.save(account) + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should contain corresponding bidders size due to config" + assert response.bidderStatus.size() == 1 + } + + def "PBS cookie sync request should capped to max limit"() { + given: "Default cookie sync request" + def accountId = PBSUtils.randomNumber + def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { + bidders = [GENERIC, BOGUS] + account = accountId + limit = limitRequest + debug = false + } + + and: "Save account with cookie config" + def cookieSyncConfig = new AccountCookieSyncConfig(maxLimit: 1) + def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) + def account = new Account(uuid: accountId, config: accountConfig) + accountDao.save(account) + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should contain corresponding bidders size due to config" + assert response.bidderStatus.size() == 1 + + where: + limitRequest << [0, 2, null] + } + + def "PBS cookie sync request should account limit override general configuration limit when not limit in request"() { + given: "Default cookie sync request" + def accountId = PBSUtils.randomNumber + def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { + bidders = [GENERIC, BOGUS] + account = accountId + limit = null + debug = false + } + + and: "Save account with cookie config" + def cookieSyncConfig = new AccountCookieSyncConfig(defaultLimit: 1) + def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) + def account = new Account(uuid: accountId, config: accountConfig) + accountDao.save(account) + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should contain corresponding bidders size due to config" + assert response.bidderStatus.size() == 1 + } + + def "PBS cookie sync request should take precedence request limit over account and global config"() { + given: "PBS config with expanded limit" + def prebidServerService = pbsServiceFactory.getService( + ["cookie-sync.default-limit": "3"] + PBS_CONFIG) + + and: "Default cookie sync request" + def accountId = PBSUtils.randomNumber + def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { + bidders = [GENERIC, BOGUS] + account = accountId + limit = 1 + debug = false + } + + and: "Save account with cookie config" + def cookieSyncConfig = new AccountCookieSyncConfig(defaultLimit: 2) + def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) + def account = new Account(uuid: accountId, config: accountConfig) + accountDao.save(account) + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should contain corresponding bidders size due to global config" + assert response.bidderStatus.size() == cookieSyncRequest.limit + } + + def "PBS cookie sync request should take presence coop sync over coop sync in cofig"() { + given: "Default cookie sync request" + def accountId = PBSUtils.randomNumber + def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { + bidders = [GENERIC, BOGUS] + account = accountId + coopSync = true + } + + and: "Save account with cookie config" + def cookieSyncConfig = new AccountCookieSyncConfig(coopSync: new AccountCoopSyncConfig(enabled: accountCoopSyncConfig)) + def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) + def account = new Account(uuid: accountId, config: accountConfig) + accountDao.save(account) + + when: "PBS processes cookie sync request" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) + + then: "Response should contain corresponding bidders size due to global config" + assert response.bidderStatus.size() == 9 + + where: + accountCoopSyncConfig << [false, true, null] + } + + private static Map getValidBidderUserSyncs(CookieSyncResponse cookieSyncResponse) { cookieSyncResponse.bidderStatus .findAll { it.userSync } .collectEntries { [it.bidder, it.userSync] } } - Map getRejectedBidderUserSyncs(CookieSyncResponse cookieSyncResponse) { + private static Map getRejectedBidderUserSyncs(CookieSyncResponse cookieSyncResponse) { cookieSyncResponse.bidderStatus .findAll { it.error } .collectEntries { [it.bidder, it.error] } diff --git a/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy index 0da24b00f2a..6e81c294ee7 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy @@ -1,9 +1,7 @@ package org.prebid.server.functional.tests import org.prebid.server.functional.model.UidsCookie -import org.prebid.server.functional.model.bidder.BidderName import org.prebid.server.functional.model.request.setuid.SetuidRequest -import org.prebid.server.functional.model.request.setuid.UidWithExpiry import org.prebid.server.functional.model.response.cookiesync.UserSyncInfo import org.prebid.server.functional.service.PrebidServerException import org.prebid.server.functional.service.PrebidServerService diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAmpSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAmpSpec.groovy index 925cc7e1f76..4525ed24c78 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAmpSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAmpSpec.groovy @@ -34,7 +34,7 @@ class GdprAmpSpec extends PrivacyBaseSpec { given: "AmpRequest with consent string" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() def ampRequest = getGdprAmpRequest(validConsentString) @@ -231,7 +231,7 @@ class GdprAmpSpec extends PrivacyBaseSpec { given: "Default AmpRequest" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() def ampRequest = getGdprAmpRequest(validConsentString) @@ -262,7 +262,7 @@ class GdprAmpSpec extends PrivacyBaseSpec { given: "Default AmpRequest" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() def ampRequest = getGdprAmpRequest(validConsentString) @@ -300,7 +300,7 @@ class GdprAmpSpec extends PrivacyBaseSpec { .setPurposesLITransparency(BASIC_ADS) .setTcfPolicyVersion(tcfPolicyVersion.value) .setVendorListVersion(tcfPolicyVersion.vendorListVersion) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() and: "AMP request" diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy index 21cbdafe9e7..f9f59d3d0f4 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy @@ -29,7 +29,7 @@ class GdprAuctionSpec extends PrivacyBaseSpec { given: "Default gdpr BidRequest" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() def bidRequest = getGdprBidRequest(validConsentString) @@ -100,7 +100,7 @@ class GdprAuctionSpec extends PrivacyBaseSpec { given: "Default basic generic BidRequest" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() def bidRequest = getGdprBidRequest(DistributionChannel.APP, validConsentString) @@ -123,7 +123,7 @@ class GdprAuctionSpec extends PrivacyBaseSpec { given: "Default basic generic BidRequest" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() def bidRequest = getGdprBidRequest(validConsentString) @@ -146,7 +146,7 @@ class GdprAuctionSpec extends PrivacyBaseSpec { given: "Default basic generic BidRequest" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() def bidRequest = getGdprBidRequest(DistributionChannel.APP, validConsentString) @@ -170,7 +170,7 @@ class GdprAuctionSpec extends PrivacyBaseSpec { given: "Default basic generic BidRequest" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() def bidRequest = getGdprBidRequest(validConsentString) @@ -194,7 +194,7 @@ class GdprAuctionSpec extends PrivacyBaseSpec { given: "BidRequest with channel: #requestChannel, gdpr" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() def bidRequest = getGdprBidRequest(validConsentString).tap { ext.prebid.channel = new Channel().tap { @@ -255,7 +255,7 @@ class GdprAuctionSpec extends PrivacyBaseSpec { .setPurposesLITransparency(BASIC_ADS) .setTcfPolicyVersion(tcfPolicyVersion.value) .setVendorListVersion(tcfPolicyVersion.vendorListVersion) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() and: "Bid request" diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/GppAuctionSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/GppAuctionSpec.groovy index 0084c50a049..0283bc1887f 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/GppAuctionSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/GppAuctionSpec.groovy @@ -147,7 +147,7 @@ class GppAuctionSpec extends PrivacyBaseSpec { given: "Default bid request with gpp and gppSid" def validConsentString = new TcfConsent.Builder() .setPurposesLITransparency(BASIC_ADS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() def gppSidIds = [TCF_EU_V2.intValue] def gpp = new TcfEuV2Consent.Builder().build() diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/GppCookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/GppCookieSyncSpec.groovy index 9e4a2715f26..9f44c987360 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/GppCookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/GppCookieSyncSpec.groovy @@ -167,7 +167,7 @@ class GppCookieSyncSpec extends BaseSpec { it.gpp = new TcfEuV2Consent.Builder().build() it.gdpr = null it.gdprConsent = new TcfConsent.Builder().setPurposesLITransparency(DEVICE_ACCESS) - .addVendorLegitimateInterest([GENERIC_VENDOR_ID]) + .setVendorLegitimateInterest([GENERIC_VENDOR_ID]) .build() } diff --git a/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy b/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy index b19a4267920..b5068719017 100644 --- a/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy +++ b/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy @@ -4,10 +4,13 @@ import com.iabtcf.encoder.TCStringEncoder import com.iabtcf.utils.BitSetIntIterable import org.prebid.server.functional.util.PBSUtils +import static org.prebid.server.functional.util.privacy.TcfConsent.TcfPolicyVersion.TCF_POLICY_V2 + class TcfConsent implements ConsentString { - public static final Integer RUBICON_VENDOR_ID = PBSUtils.getRandomNumber(0, 65534) + public static final Integer RUBICON_VENDOR_ID = PBSUtils.getRandomNumber(0, 5000) public static final Integer GENERIC_VENDOR_ID = RUBICON_VENDOR_ID + public static final Integer VENDOR_RUBICON_ID = 33 private final TCStringEncoder.Builder tcStringEncoder @@ -32,8 +35,8 @@ class TcfConsent implements ConsentString { Builder() { tcStringEncoder = TCStringEncoder.newBuilder() setVersion(2) - setTcfPolicyVersion(2) - setVendorListVersion(2) + setTcfPolicyVersion(TCF_POLICY_V2.value) + setVendorListVersion(TCF_POLICY_V2.vendorListVersion) } Builder setVersion(Integer version) { @@ -61,7 +64,7 @@ class TcfConsent implements ConsentString { this } - Builder addVendorLegitimateInterest(List vendorLegitimateInterest) { + Builder setVendorLegitimateInterest(List vendorLegitimateInterest) { tcStringEncoder.addVendorLegitimateInterest(BitSetIntIterable.from(vendorLegitimateInterest)) this } From 50d07ba4fa807ffbecff0094e0e5644e4058038b Mon Sep 17 00:00:00 2001 From: Markiyan Mykush <95693607+marki1an@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:40:54 +0300 Subject: [PATCH 02/16] Tests: Update `vendor list response` (#2605) --- .../vendorlist/VendorListResponse.groovy | 7 ++----- .../scaffolding/VendorList.groovy | 18 +++++++++++------- .../tests/privacy/GdprAmpSpec.groovy | 2 +- .../tests/privacy/GdprAuctionSpec.groovy | 2 +- .../functional/util/privacy/TcfConsent.groovy | 8 ++++---- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy b/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy index 84f569599ab..4e3804b66f8 100644 --- a/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy @@ -5,8 +5,7 @@ import org.prebid.server.functional.util.PBSUtils import java.time.Clock import java.time.ZonedDateTime -import static org.prebid.server.functional.util.privacy.TcfConsent.GENERIC_VENDOR_ID -import static org.prebid.server.functional.util.privacy.TcfConsent.VENDOR_RUBICON_ID +import static org.prebid.server.functional.util.privacy.TcfConsent.VENDOR_LIST_VERSION class VendorListResponse { @@ -19,10 +18,8 @@ class VendorListResponse { static VendorListResponse getDefaultVendorListResponse() { new VendorListResponse().tap { it.gvlSpecificationVersion = 2 - it.tcfPolicyVersion = 2 + it.vendorListVersion = VENDOR_LIST_VERSION it.lastUpdated = ZonedDateTime.now(Clock.systemUTC()).minusWeeks(2) - it.vendors = [(GENERIC_VENDOR_ID): Vendor.getDefaultVendor(GENERIC_VENDOR_ID), - (VENDOR_RUBICON_ID): Vendor.getDefaultVendor(VENDOR_RUBICON_ID)] } } diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy index 9c1782bfacd..a469241aeae 100644 --- a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy @@ -4,12 +4,14 @@ import org.mockserver.matchers.TimeToLive import org.mockserver.matchers.Times import org.mockserver.model.HttpRequest import org.mockserver.model.HttpResponse -import org.prebid.server.functional.model.mock.services.vendorlist.VendorListResponse import org.testcontainers.containers.MockServerContainer import static org.mockserver.model.HttpRequest.request import static org.mockserver.model.HttpResponse.response import static org.mockserver.model.HttpStatusCode.OK_200 +import static org.prebid.server.functional.model.mock.services.vendorlist.VendorListResponse.getDefaultVendorListResponse +import static org.prebid.server.functional.model.mock.services.vendorlist.VendorListResponse.Vendor +import static org.prebid.server.functional.util.privacy.TcfConsent.GENERIC_VENDOR_ID import static org.prebid.server.functional.util.privacy.TcfConsent.TcfPolicyVersion import static org.prebid.server.functional.util.privacy.TcfConsent.TcfPolicyVersion.TCF_POLICY_V2 @@ -31,15 +33,17 @@ class VendorList extends NetworkScaffolding { request().withPath(VENDOR_LIST_ENDPOINT) } - void setResponse(TcfPolicyVersion tcfPolicyVersion = TCF_POLICY_V2) { + void setResponse(TcfPolicyVersion tcfPolicyVersion = TCF_POLICY_V2, + Map vendors = [(GENERIC_VENDOR_ID): Vendor.getDefaultVendor(GENERIC_VENDOR_ID)]) { def prepareEndpoint = endpoint.replace("{TCF_POLICY}", "v" + tcfPolicyVersion.vendorListVersion) - def prepareEncodeResponseBody = encode(VendorListResponse.defaultVendorListResponse.tap { - it.vendorListVersion = tcfPolicyVersion.vendorListVersion + def prepareEncodeResponseBody = encode(defaultVendorListResponse.tap { + it.tcfPolicyVersion = tcfPolicyVersion.vendorListVersion + it.vendors = vendors }) mockServerClient.when(request().withPath(prepareEndpoint), Times.unlimited(), TimeToLive.unlimited(), -10) - .respond {request -> request.withPath(endpoint) - ? response().withStatusCode(OK_200.code()).withBody(prepareEncodeResponseBody) - : HttpResponse.notFoundResponse()} + .respond { request -> request.withPath(endpoint) + ? response().withStatusCode(OK_200.code()).withBody(prepareEncodeResponseBody) + : HttpResponse.notFoundResponse()} } } diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAmpSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAmpSpec.groovy index 929f39616ec..90a279e1df6 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAmpSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAmpSpec.groovy @@ -330,7 +330,7 @@ class GdprAmpSpec extends PrivacyBaseSpec { def properVendorListPath = "/app/prebid-server/data/vendorlist-v${tcfPolicyVersion.vendorListVersion}/${tcfPolicyVersion.vendorListVersion}.json" PBSUtils.waitUntil { privacyPbsService.isFileExist(properVendorListPath) } def vendorList = privacyPbsService.getValueFromContainer(properVendorListPath, VendorListConsent.class) - assert vendorList.vendorListVersion == tcfPolicyVersion.vendorListVersion + assert vendorList.tcfPolicyVersion == tcfPolicyVersion.vendorListVersion and: "Logs should contain proper vendor list version" def logs = privacyPbsService.getLogsByTime(startTime) diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy index 1a02c4a4a5c..bc1ce898df8 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy @@ -278,7 +278,7 @@ class GdprAuctionSpec extends PrivacyBaseSpec { def properVendorListPath = "/app/prebid-server/data/vendorlist-v${tcfPolicyVersion.vendorListVersion}/${tcfPolicyVersion.vendorListVersion}.json" PBSUtils.waitUntil { privacyPbsService.isFileExist(properVendorListPath) } def vendorList = privacyPbsService.getValueFromContainer(properVendorListPath, VendorListConsent.class) - assert vendorList.vendorListVersion == tcfPolicyVersion.vendorListVersion + assert vendorList.tcfPolicyVersion == tcfPolicyVersion.vendorListVersion and: "Logs should contain proper vendor list version" def logs = privacyPbsService.getLogsByTime(startTime) diff --git a/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy b/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy index b5068719017..e2b616b8190 100644 --- a/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy +++ b/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy @@ -8,9 +8,9 @@ import static org.prebid.server.functional.util.privacy.TcfConsent.TcfPolicyVers class TcfConsent implements ConsentString { - public static final Integer RUBICON_VENDOR_ID = PBSUtils.getRandomNumber(0, 5000) - public static final Integer GENERIC_VENDOR_ID = RUBICON_VENDOR_ID - public static final Integer VENDOR_RUBICON_ID = 33 + public static final Integer RUBICON_VENDOR_ID = PBSUtils.getRandomNumber(0, 65534) + public static final Integer GENERIC_VENDOR_ID = PBSUtils.getRandomNumber(0, 65534) + public static final Integer VENDOR_LIST_VERSION = PBSUtils.getRandomNumber(0, 4095) private final TCStringEncoder.Builder tcStringEncoder @@ -36,7 +36,7 @@ class TcfConsent implements ConsentString { tcStringEncoder = TCStringEncoder.newBuilder() setVersion(2) setTcfPolicyVersion(TCF_POLICY_V2.value) - setVendorListVersion(TCF_POLICY_V2.vendorListVersion) + setVendorListVersion(VENDOR_LIST_VERSION) } Builder setVersion(Integer version) { From e3583762cbd1c13feb70ea72c0e34c1fc0f8cab3 Mon Sep 17 00:00:00 2001 From: Markiyan Mykush <95693607+marki1an@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:43:49 +0300 Subject: [PATCH 03/16] Move from io.restassured.http.Headers to Map<> (#2603) --- .../functional/model/response/setuid/SetuidResponse.groovy | 3 +-- .../server/functional/service/PrebidServerService.groovy | 2 +- .../org/prebid/server/functional/tests/SetUidSpec.groovy | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/model/response/setuid/SetuidResponse.groovy b/src/test/groovy/org/prebid/server/functional/model/response/setuid/SetuidResponse.groovy index 3eb9aebc0d3..bc35cd07d82 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/setuid/SetuidResponse.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/setuid/SetuidResponse.groovy @@ -1,13 +1,12 @@ package org.prebid.server.functional.model.response.setuid import groovy.transform.ToString -import io.restassured.http.Headers import org.prebid.server.functional.model.UidsCookie @ToString(includeNames = true, ignoreNulls = true) class SetuidResponse { - Headers headers + Map headers UidsCookie uidsCookie Byte[] responseBody } 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 58bee588be0..9ad908fb053 100644 --- a/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy +++ b/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy @@ -173,7 +173,7 @@ class PrebidServerService implements ObjectMapperWrapper { def setuidResponse = new SetuidResponse() setuidResponse.uidsCookie = getDecodedUidsCookie(response) setuidResponse.responseBody = response.asByteArray() - setuidResponse.headers = response.headers() + setuidResponse.headers = getHeaders(response) setuidResponse } diff --git a/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy index 6e81c294ee7..b9e310c2b26 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy @@ -268,7 +268,7 @@ class SetUidSpec extends BaseSpec { assert response.uidsCookie.tempUIDs[OPENX] and: "Response set cookie header size should be lowest or the same as max cookie config size" - assert response.headers.get("Set-Cookie").value.split("Secure;")[0].length() <= MAX_COOKIE_SIZE + assert response.headers.get("Set-Cookie").split("Secure;")[0].length() <= MAX_COOKIE_SIZE and: "Request bidder should contain uid from Set uid request" assert response.uidsCookie.tempUIDs[OPENX].uid == request.uid From a9f873c8f7b774605b3e8aa88b10ab9614de9929 Mon Sep 17 00:00:00 2001 From: markiian Date: Wed, 6 Sep 2023 22:02:13 +0300 Subject: [PATCH 04/16] Clean up code --- .../server/functional/tests/BaseSpec.groovy | 4 ++ .../functional/tests/CookieSyncSpec.groovy | 38 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/BaseSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/BaseSpec.groovy index 442c9574d9c..f681998f033 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/BaseSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/BaseSpec.groovy @@ -10,6 +10,7 @@ import org.prebid.server.functional.testcontainers.Dependencies import org.prebid.server.functional.testcontainers.PbsServiceFactory import org.prebid.server.functional.testcontainers.scaffolding.Bidder import org.prebid.server.functional.testcontainers.scaffolding.PrebidCache +import org.prebid.server.functional.testcontainers.scaffolding.VendorList import org.prebid.server.functional.util.ObjectMapperWrapper import org.prebid.server.functional.util.PBSUtils import spock.lang.Specification @@ -22,6 +23,7 @@ abstract class BaseSpec extends Specification implements ObjectMapperWrapper { protected static final PbsServiceFactory pbsServiceFactory = new PbsServiceFactory(networkServiceContainer) protected static final Bidder bidder = new Bidder(networkServiceContainer) + protected static final VendorList vendorList = new VendorList(networkServiceContainer) protected static final PrebidCache prebidCache = new PrebidCache(networkServiceContainer) protected static final HibernateRepositoryService repository = new HibernateRepositoryService(Dependencies.mysqlContainer) @@ -40,12 +42,14 @@ abstract class BaseSpec extends Specification implements ObjectMapperWrapper { def setupSpec() { prebidCache.setResponse() bidder.setResponse() + vendorList.setResponse() } def cleanupSpec() { bidder.reset() prebidCache.reset() repository.removeAllDatabaseData() + vendorList.reset() } protected static int getRandomTimeout() { diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index bab6e1606e5..6c79d5181dc 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -45,57 +45,53 @@ import static org.prebid.server.functional.testcontainers.Dependencies.networkSe import static org.prebid.server.functional.util.privacy.CcpaConsent.Signal.ENFORCED import static org.prebid.server.functional.util.privacy.TcfConsent.GENERIC_VENDOR_ID import static org.prebid.server.functional.util.privacy.TcfConsent.PurposeId.BASIC_ADS +import static org.prebid.server.functional.util.privacy.TcfConsent.RUBICON_VENDOR_ID class CookieSyncSpec extends BaseSpec { private static final UserSyncInfo.Type USER_SYNC_TYPE = REDIRECT private static final boolean CORS_SUPPORT = false private static final String USER_SYNC_URL = "$networkServiceContainer.rootUri/generic-usersync" - private static final Map GDPR_VENDOR_LIST_CONFIG = ["gdpr.vendorlist.v2.http-endpoint-template": "$networkServiceContainer.rootUri/v2/vendor-list.json".toString(), - "gdpr.vendorlist.v3.http-endpoint-template": "$networkServiceContainer.rootUri/v3/vendor-list.json".toString()] + private static final Map GENERIC_CONFIG = [ "adapters.${GENERIC.value}.usersync.redirect.url" : USER_SYNC_URL, - "adapters.${GENERIC.value}.usersync.redirect.support-cors": "false", + "adapters.${GENERIC.value}.usersync.redirect.support-cors": CORS_SUPPORT as String, "adapters.${GENERIC.value}.meta-info.vendor-id" : GENERIC_VENDOR_ID as String] private static final Map ACEEX_CONFIG = [ "adapters.${ACEEX.value}.enabled" : "true", "adapters.${ACEEX.value}.usersync.cookie-family-name" : ACEEX.value, "adapters.${ACEEX.value}.usersync.redirect.url" : "https://test.redirect.endpoint.com={{redirect_url}}", - "adapters.${ACEEX.value}.usersync.redirect.support-cors": "false"] + "adapters.${ACEEX.value}.usersync.redirect.support-cors": CORS_SUPPORT as String] private static final Map RUBICON_CONFIG = [ "adapters.${RUBICON.value}.enabled" : "true", - "adapters.${RUBICON.value}.meta-info.vendor-id" : 33 as String, + "adapters.${RUBICON.value}.meta-info.vendor-id" : RUBICON_VENDOR_ID as String, "adapters.${RUBICON.value}.usersync.cookie-family-name" : RUBICON.value, "adapters.${RUBICON.value}.usersync.redirect.url" : "https://test.redirect.endpoint.com", - "adapters.${RUBICON.value}.usersync.redirect.support-cors": "false", + "adapters.${RUBICON.value}.usersync.redirect.support-cors": CORS_SUPPORT as String, "adapters.${RUBICON.value}.usersync.iframe.url" : "https://test.iframe.endpoint.com&redir={{redirect_url}}", - "adapters.${RUBICON.value}.usersync.iframe.support-cors" : "false"] + "adapters.${RUBICON.value}.usersync.iframe.support-cors" : CORS_SUPPORT as String] private static final Map OPENX_CONFIG = [ "adapters.${OPENX.value}.enabled" : "true", "adapters.${OPENX.value}.usersync.cookie-family-name" : OPENX.value, "adapters.${OPENX.value}.usersync.redirect.url" : USER_SYNC_URL, - "adapters.${OPENX.value}.usersync.redirect.support-cors": "false", + "adapters.${OPENX.value}.usersync.redirect.support-cors": CORS_SUPPORT as String, "adapters.${OPENX.value}.usersync.iframe.url" : USER_SYNC_URL, - "adapters.${OPENX.value}.usersync.iframe.support-cors" : "false"] + "adapters.${OPENX.value}.usersync.iframe.support-cors" : CORS_SUPPORT as String] private static final Map APPNEXUS_CONFIG = [ "adapters.${APPNEXUS.value}.enabled" : "true", "adapters.${APPNEXUS.value}.usersync.cookie-family-name" : APPNEXUS.value, "adapters.${APPNEXUS.value}.usersync.redirect.url" : "https://test.appnexus.redirect.com/getuid?{{redirect_url}}", - "adapters.${APPNEXUS.value}.usersync.redirect.support-cors": "false", + "adapters.${APPNEXUS.value}.usersync.redirect.support-cors": CORS_SUPPORT as String, "adapters.${APPNEXUS.value}.usersync.iframe.url" : "https://test.iframe.endpoint.com", - "adapters.${APPNEXUS.value}.usersync.iframe.support-cors" : "false"] - private static final Map AAX_CONFIG = ["adapters.${AAX.value}.enabled": "true"] + "adapters.${APPNEXUS.value}.usersync.iframe.support-cors" : CORS_SUPPORT as String] + private static final Map AAX_CONFIG = ["adapters.${AAX.value}.enabled": "true"] private static final Map ACUITYADS_CONFIG = ["adapters.${ACUITYADS.value}.enabled": "true"] - private static final Map ADKERNEL_CONFIG = ["adapters.${ADKERNEL.value}.enabled": "true"] + private static final Map ADKERNEL_CONFIG = ["adapters.${ADKERNEL.value}.enabled": "true"] private static final Map PBS_CONFIG = APPNEXUS_CONFIG + RUBICON_CONFIG + OPENX_CONFIG + - GENERIC_CONFIG + ACEEX_CONFIG + AAX_CONFIG + ACUITYADS_CONFIG + ADKERNEL_CONFIG + - GDPR_VENDOR_LIST_CONFIG + ["cookie-sync.pri": "grid, ix, adkernel"] + GENERIC_CONFIG + ACEEX_CONFIG + AAX_CONFIG + ACUITYADS_CONFIG + ADKERNEL_CONFIG + ["cookie-sync.pri": "grid, ix, adkernel"] private final PrebidServerService prebidServerService = pbsServiceFactory.getService(PBS_CONFIG) - private final VendorList vendorListResponse = new VendorList(networkServiceContainer).tap { - setResponse() - } def "PBS cookie sync request should replace synced as family bidder and fill up response with enabled bidders to the limit in request"() { given: "PBS config with alias bidder without cookie family name" @@ -1627,7 +1623,7 @@ class CookieSyncSpec extends BaseSpec { def bidderStatus = response?.bidderStatus?.userSync assert bidderStatus?.url assert bidderStatus?.type - assert bidderStatus?.supportCORS?.every(it -> it == false) + assert bidderStatus?.supportCORS?.every(it -> it == CORS_SUPPORT) } def "PBS cookie sync request shouldn't return sync url when active uids cookie is present for bidder"() { @@ -1675,7 +1671,7 @@ class CookieSyncSpec extends BaseSpec { } def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) - and: "Set up appnexus uids cookie" + and: "Set up uids cookie with appnexus" def uidsCookie = UidsCookie.getDefaultUidsCookie(APPNEXUS) when: "PBS processes cookie sync request with generic uid cookies" @@ -2159,7 +2155,7 @@ class CookieSyncSpec extends BaseSpec { assert response.bidderStatus.size() == cookieSyncRequest.limit } - def "PBS cookie sync request should take presence coop sync over coop sync in cofig"() { + def "PBS cookie sync request should take presence coop sync over coop sync in config"() { given: "Default cookie sync request" def accountId = PBSUtils.randomNumber def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap { From 9de7a0e3c3f7baf50d060364535c977471212580 Mon Sep 17 00:00:00 2001 From: markiian Date: Thu, 7 Sep 2023 16:08:31 +0300 Subject: [PATCH 05/16] Update after review --- .../service/PrebidServerService.groovy | 16 ++++---------- .../functional/tests/CookieSyncSpec.groovy | 22 ++++++++++--------- 2 files changed, 16 insertions(+), 22 deletions(-) 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 9ad908fb053..d2a98fcb7f4 100644 --- a/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy +++ b/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy @@ -119,7 +119,7 @@ class PrebidServerService implements ObjectMapperWrapper { @Step("[POST] /cookie_sync without cookie") CookieSyncResponse sendCookieSyncRequest(CookieSyncRequest request) { - def response = postCookieSync(request, null) + def response = postCookieSync(request) checkResponseStatusCode(response) response.as(CookieSyncResponse) @@ -127,7 +127,7 @@ class PrebidServerService implements ObjectMapperWrapper { @Step("[POST] /cookie_sync with headers") CookieSyncResponse sendCookieSyncRequest(CookieSyncRequest request, Map headers) { - def response = postCookieSync(request, headers) + def response = postCookieSync(request, null, headers) checkResponseStatusCode(response) response.as(CookieSyncResponse) @@ -135,7 +135,7 @@ class PrebidServerService implements ObjectMapperWrapper { @Step("[POST] /cookie_sync with uids cookie") CookieSyncResponse sendCookieSyncRequest(CookieSyncRequest request, UidsCookie uidsCookie) { - def response = postCookieSync(request, uidsCookie, null) + def response = postCookieSync(request, uidsCookie) checkResponseStatusCode(response) response.as(CookieSyncResponse) @@ -318,21 +318,13 @@ class PrebidServerService implements ObjectMapperWrapper { .post(AUCTION_ENDPOINT) } - private Response postCookieSync(CookieSyncRequest cookieSyncRequest, Map header) { - postCookieSync(cookieSyncRequest, null, header) - } - private Response postCookieSync(CookieSyncRequest cookieSyncRequest, UidsCookie uidsCookie = null, Map additionalCookies = null, Map header = null, String uidsAudit = null) { - def cookies = [:] - - if (additionalCookies) { - cookies.putAll(additionalCookies) - } + def cookies = additionalCookies ?: [:] if (uidsCookie) { cookies.put(UIDS_COOKIE_NAME, Base64.urlEncoder.encodeToString(encode(uidsCookie).bytes)) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index 6c79d5181dc..a3160ce4697 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -52,6 +52,8 @@ class CookieSyncSpec extends BaseSpec { private static final UserSyncInfo.Type USER_SYNC_TYPE = REDIRECT private static final boolean CORS_SUPPORT = false private static final String USER_SYNC_URL = "$networkServiceContainer.rootUri/generic-usersync" + private static final String ALL_BIDDERS = "*" + private static final String DEFAULT_PBS_BIDDERS_SIZE = 8 private static final Map GENERIC_CONFIG = [ "adapters.${GENERIC.value}.usersync.redirect.url" : USER_SYNC_URL, @@ -84,9 +86,9 @@ class CookieSyncSpec extends BaseSpec { "adapters.${APPNEXUS.value}.usersync.redirect.support-cors": CORS_SUPPORT as String, "adapters.${APPNEXUS.value}.usersync.iframe.url" : "https://test.iframe.endpoint.com", "adapters.${APPNEXUS.value}.usersync.iframe.support-cors" : CORS_SUPPORT as String] - private static final Map AAX_CONFIG = ["adapters.${AAX.value}.enabled": "true"] + private static final Map AAX_CONFIG = ["adapters.${AAX.value}.enabled": "true"] private static final Map ACUITYADS_CONFIG = ["adapters.${ACUITYADS.value}.enabled": "true"] - private static final Map ADKERNEL_CONFIG = ["adapters.${ADKERNEL.value}.enabled": "true"] + private static final Map ADKERNEL_CONFIG = ["adapters.${ADKERNEL.value}.enabled": "true"] private static final Map PBS_CONFIG = APPNEXUS_CONFIG + RUBICON_CONFIG + OPENX_CONFIG + GENERIC_CONFIG + ACEEX_CONFIG + AAX_CONFIG + ACUITYADS_CONFIG + ADKERNEL_CONFIG + ["cookie-sync.pri": "grid, ix, adkernel"] @@ -1481,7 +1483,7 @@ class CookieSyncSpec extends BaseSpec { def "PBS cookie sync request should exclude all iframe bidders when asterisk present in bidders filterSettings"() { given: "Empty cookie sync request body" def filterSettings = new FilterSettings().tap { - iframe = new MethodFilter(bidders: "*", filter: EXCLUDE) + iframe = new MethodFilter(bidders: ALL_BIDDERS, filter: EXCLUDE) } def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) @@ -1501,7 +1503,7 @@ class CookieSyncSpec extends BaseSpec { def "PBS cookie sync request should exclude all image bidders when asterisk present in bidders filterSettings"() { given: "Empty cookie sync request body" def filterSettings = new FilterSettings().tap { - image = new MethodFilter(bidders: "*", filter: EXCLUDE) + image = new MethodFilter(bidders: ALL_BIDDERS, filter: EXCLUDE) } def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) @@ -1821,7 +1823,7 @@ class CookieSyncSpec extends BaseSpec { then: "Response should have status 'NO_COOKIE'" assert response.status == NO_COOKIE - and: "Response shouldn't contain proper" + and: "Response shouldn't contain amount of invalid bidder" assert response.getBidderStatus().size() == 0 where: @@ -1838,7 +1840,7 @@ class CookieSyncSpec extends BaseSpec { then: "Response should have status 'NO_COOKIE'" assert response.status == NO_COOKIE - and: "Response shouldn't contain proper" + and: "Response should contain amount of bidder that define in request" assert response.getBidderStatus().size() == cookieSyncRequest.limit where: @@ -1859,11 +1861,11 @@ class CookieSyncSpec extends BaseSpec { then: "Response should have status 'NO_COOKIE'" assert response.status == NO_COOKIE - and: "Response shouldn't contain proper" + and: "Response should contain amount of bidder that define in request" assert response.getBidderStatus().size() == cookieSyncRequest.limit } - def "PBS cookie sync request should return all users sync bidders when limit is null"() { + def "PBS cookie sync request should return eight users sync bidders when limit isn't define"() { given: "Empty cookie sync request body" def cookieSyncRequest = new CookieSyncRequest().tap { limit = null @@ -1876,8 +1878,8 @@ class CookieSyncSpec extends BaseSpec { then: "Response should have status 'NO_COOKIE'" assert response.status == NO_COOKIE - and: "Response should contain configured bidders" - assert response?.getBidderStatus()?.size() == 8 + and: "Response should contain eight bidder by default" + assert response?.getBidderStatus()?.size() == DEFAULT_PBS_BIDDERS_SIZE } def "PBS cookie sync request should limit the number of returned bidders"() { From 8d8bc04ccdbf75a5839e8b21507ef532f7d43ddc Mon Sep 17 00:00:00 2001 From: markiian Date: Thu, 7 Sep 2023 22:05:22 +0300 Subject: [PATCH 06/16] Minor update --- .../org/prebid/server/functional/tests/CookieSyncSpec.groovy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index a3160ce4697..ea3ca6eee78 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -15,7 +15,6 @@ import org.prebid.server.functional.model.request.cookiesync.MethodFilter import org.prebid.server.functional.model.response.cookiesync.CookieSyncResponse import org.prebid.server.functional.model.response.cookiesync.UserSyncInfo import org.prebid.server.functional.service.PrebidServerService -import org.prebid.server.functional.testcontainers.scaffolding.VendorList import org.prebid.server.functional.util.HttpUtil import org.prebid.server.functional.util.PBSUtils import org.prebid.server.functional.util.privacy.CcpaConsent @@ -53,7 +52,7 @@ class CookieSyncSpec extends BaseSpec { private static final boolean CORS_SUPPORT = false private static final String USER_SYNC_URL = "$networkServiceContainer.rootUri/generic-usersync" private static final String ALL_BIDDERS = "*" - private static final String DEFAULT_PBS_BIDDERS_SIZE = 8 + private static final Integer DEFAULT_PBS_BIDDERS_SIZE = 8 private static final Map GENERIC_CONFIG = [ "adapters.${GENERIC.value}.usersync.redirect.url" : USER_SYNC_URL, From 9c5db8201b46279a95c44a9bdf02cf1d1671a406 Mon Sep 17 00:00:00 2001 From: markiian Date: Tue, 24 Oct 2023 14:26:38 +0300 Subject: [PATCH 07/16] Update after review --- .../functional/model/bidder/BidderName.groovy | 2 +- .../services/vendorlist/VendorListResponse.groovy | 2 +- .../model/request/cookiesync/MethodFilter.groovy | 1 - .../functional/service/PrebidServerService.groovy | 15 +-------------- .../server/functional/tests/CookieSyncSpec.groovy | 15 --------------- 5 files changed, 3 insertions(+), 32 deletions(-) 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 4419a4628ef..957bfc4c5ab 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 @@ -5,7 +5,7 @@ import net.minidev.json.annotate.JsonIgnore enum BidderName { - ALIAS, GENERIC, RUBICON, APPNEXUS, BOGUS, OPENX, ACEEX, ACUITYADS, GRID, AAX, ADKERNEL, MEDIANET + BOGUS, ALIAS, GENERIC, APPNEXUS, ACEEX, ACUITYADS, AAX, ADKERNEL, GRID, MEDIANET, OPENX, RUBICON @JsonValue String getValue() { diff --git a/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy b/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy index 4e3804b66f8..7d61d88ff41 100644 --- a/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy @@ -41,7 +41,7 @@ class VendorListResponse { Boolean usesNonCookieAccess Boolean deviceStorageDisclosureUrl - static Vendor getDefaultVendor(Integer id) { + static Vendor getDefaultVendor(int id) { new Vendor().tap { it.id = id it.name = PBSUtils.randomString diff --git a/src/test/groovy/org/prebid/server/functional/model/request/cookiesync/MethodFilter.groovy b/src/test/groovy/org/prebid/server/functional/model/request/cookiesync/MethodFilter.groovy index 0a74beaecb6..d17bdad113c 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/cookiesync/MethodFilter.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/cookiesync/MethodFilter.groovy @@ -5,7 +5,6 @@ import groovy.transform.ToString @ToString(includeNames = true, ignoreNulls = true) class MethodFilter { - // Here we use wildcard for different compatibility T bidders FilterType filter } 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 d2a98fcb7f4..0b852aa3a8e 100644 --- a/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy +++ b/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy @@ -141,14 +141,6 @@ class PrebidServerService implements ObjectMapperWrapper { response.as(CookieSyncResponse) } - @Step("[POST] /cookie_sync with uids cookie") - CookieSyncResponse sendCookieSyncRequest(CookieSyncRequest request, String uidsCookie) { - def response = postCookieSync(request, null, null, null, uidsCookie) - - checkResponseStatusCode(response) - response.as(CookieSyncResponse) - } - @Step("[POST] /cookie_sync with uids and additional cookies") CookieSyncResponse sendCookieSyncRequest(CookieSyncRequest request, UidsCookie uidsCookie, @@ -321,8 +313,7 @@ class PrebidServerService implements ObjectMapperWrapper { private Response postCookieSync(CookieSyncRequest cookieSyncRequest, UidsCookie uidsCookie = null, Map additionalCookies = null, - Map header = null, - String uidsAudit = null) { + Map header = null) { def cookies = additionalCookies ?: [:] @@ -330,10 +321,6 @@ class PrebidServerService implements ObjectMapperWrapper { cookies.put(UIDS_COOKIE_NAME, Base64.urlEncoder.encodeToString(encode(uidsCookie).bytes)) } - if (uidsAudit) { - cookies.put("uids-audit", uidsAudit) - } - postCookieSync(cookieSyncRequest, cookies, header) } diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index ea3ca6eee78..40e408c0f96 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -1999,21 +1999,6 @@ class CookieSyncSpec extends BaseSpec { assert response.getBidderUserSync(RUBICON) } - def "PBS cookie sync request should ignore uids audit cookie outside of gdpr"() { - given: "Cookie sync request body" - def cookieSyncRequest = new CookieSyncRequest().tap { - bidders = [APPNEXUS] - coopSync = false - gdpr = 0 - } - - when: "PBS processes cookie sync request with cookies" - def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest, "GzhqHDTACWuj-m1FXJic6E0Vp8brrzoQDFmowPV1LQu3B5VuyOoHmyKnfRjnh-pZeKwfXVaa7TzbxxSsbYLFODxiWQptNHFKQhSTwHW5jeNbQ18Im3wwdxsPI_5nkH5zsIrfi9WP57D_6Sg23EnYeg3kBJXMAZVdb_RA8ie7ubjfC_0PMVTtZqs-Kcul81yp") - - then: "Response should contain error" - assert response.getBidderUserSync(APPNEXUS) - } - def "PBS cookie sync request shouldn't limit bidders with zero value in config"() { given: "Default cookie sync request" def accountId = PBSUtils.randomNumber From 24d8540f225c18ba067d4819e5511a7661578a0c Mon Sep 17 00:00:00 2001 From: markiian Date: Fri, 27 Oct 2023 15:20:59 +0300 Subject: [PATCH 08/16] Remove flaky tests --- .../functional/model/bidder/BidderName.groovy | 8 ++++++- .../functional/tests/CookieSyncSpec.groovy | 22 ++----------------- 2 files changed, 9 insertions(+), 21 deletions(-) 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 bcbb908d357..a27e542b127 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 @@ -13,7 +13,13 @@ enum BidderName { RUBICON("rubicon"), APPNEXUS("appnexus"), RUBICON_ALIAS("rubiconAlias"), - OPENX("openx") + OPENX("openx"), + ACEEX("aceex"), + ACUITYADS("acuityads"), + AAX("aax"), + ADKERNEL("adkernel"), + GRID("grid"), + MEDIANET("medianet") @JsonValue final String value diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index 40e408c0f96..b48b3eebd32 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -90,7 +90,8 @@ class CookieSyncSpec extends BaseSpec { private static final Map ADKERNEL_CONFIG = ["adapters.${ADKERNEL.value}.enabled": "true"] private static final Map PBS_CONFIG = APPNEXUS_CONFIG + RUBICON_CONFIG + OPENX_CONFIG + - GENERIC_CONFIG + ACEEX_CONFIG + AAX_CONFIG + ACUITYADS_CONFIG + ADKERNEL_CONFIG + ["cookie-sync.pri": "grid, ix, adkernel"] + GENERIC_CONFIG + ACEEX_CONFIG + AAX_CONFIG + ACUITYADS_CONFIG + ADKERNEL_CONFIG + + ["cookie-sync.pri": "grid, ix, adkernel"] private final PrebidServerService prebidServerService = pbsServiceFactory.getService(PBS_CONFIG) @@ -1895,25 +1896,6 @@ class CookieSyncSpec extends BaseSpec { assert response.getBidderStatus().size() == cookieSyncRequest.limit } - def "PBS cookie sync request should return randomized bidder list"() { - given: "Cookie sync request body" - def cookieSyncRequest = new CookieSyncRequest().tap { - it.limit = 2 - it.coopSync = coopSync - it.bidders = [GENERIC, RUBICON, APPNEXUS, ACEEX, OPENX] - } - - when: "PBS processes cookie sync request without cookies" - def firstResponse = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) - def secondResponse = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) - - then: "Response should have status 'NO_COOKIE'" - assert firstResponse.bidderStatus.bidder != secondResponse.bidderStatus.bidder - - where: - coopSync << [true, false] - } - def "PBS cookie sync request should return bidders matched in bidders and filter settings"() { given: "Cookie sync request body" def cookieSyncRequest = new CookieSyncRequest().tap { From 7f1a7ff951c78226e2d5fb11188554964ffb1828 Mon Sep 17 00:00:00 2001 From: markiian Date: Fri, 10 Nov 2023 14:24:48 +0200 Subject: [PATCH 09/16] Update few func tests to proper one --- .../prebid/server/functional/tests/CurrencySpec.groovy | 8 ++++++++ .../prebid/server/functional/tests/SmokeSpec.groovy | 10 +--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CurrencySpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CurrencySpec.groovy index 9fbe0f52b67..f755e85930a 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CurrencySpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CurrencySpec.groovy @@ -26,6 +26,14 @@ class CurrencySpec extends BaseSpec { } private static final PrebidServerService pbsService = pbsServiceFactory.getService(externalCurrencyConverterConfig) + def "PBS should return currency rates"() { + when: "PBS processes bidders params request" + def response = pbsService.sendCurrencyRatesRequest() + + then: "Response should contain bidders params" + assert response.rates?.size() > 0 + } + def "PBS should use default server currency if not specified in the request"() { given: "Default BidRequest without currency" def bidRequest = BidRequest.defaultBidRequest.tap { cur = null } diff --git a/src/test/groovy/org/prebid/server/functional/tests/SmokeSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/SmokeSpec.groovy index 826057ff19a..d12334da01b 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/SmokeSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/SmokeSpec.groovy @@ -73,7 +73,7 @@ class SmokeSpec extends BaseSpec { then: "Response should contain bidder uids" assert response.buyeruids?.size() == uidsCookie.tempUIDs.size() - assert response.buyeruids.every { bidder, uid -> uidsCookie.tempUIDs[bidderNameByString(bidder)].uid == uid } + assert response.buyeruids["generic"] == uidsCookie.tempUIDs[GENERIC].uid } def "PBS should return tracking pixel on event request"() { @@ -131,14 +131,6 @@ class SmokeSpec extends BaseSpec { assert response.parameters.size() > 0 } - def "PBS should return currency rates"() { - when: "PBS processes bidders params request" - def response = defaultPbsService.sendCurrencyRatesRequest() - - then: "Response should contain bidders params" - assert response.rates?.size() > 0 - } - def "PBS should return empty body on httpinteraction request"() { given: "Default httpInteractionRequest" def request = HttpInteractionRequest.defaultHttpInteractionRequest From c8ced289aaa6d35b865750f8acb1382d1081d29e Mon Sep 17 00:00:00 2001 From: markiian Date: Fri, 10 Nov 2023 16:40:49 +0200 Subject: [PATCH 10/16] Update flaky func tests --- .../tests/pricefloors/PriceFloorsSignalingSpec.groovy | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy index 796e976bef5..cdffe6f51b2 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy @@ -17,6 +17,7 @@ import org.prebid.server.functional.model.request.auction.Video import org.prebid.server.functional.model.response.auction.BidResponse import org.prebid.server.functional.model.response.auction.MediaType import org.prebid.server.functional.util.PBSUtils +import spock.lang.RepeatUntilFailure import static org.mockserver.model.HttpStatusCode.BAD_REQUEST_400 import static org.prebid.server.functional.model.Currency.USD @@ -410,9 +411,10 @@ class PriceFloorsSignalingSpec extends PriceFloorsBaseSpec { true | null | false } + @RepeatUntilFailure def "PBS should choose most aggressive adjustment when request contains multiple media-types"() { given: "BidRequest with bidAdjustment" - def bidAdjustment = PBSUtils.roundDecimal(PBSUtils.getRandomDecimal(0, 10), 1) + def bidAdjustment = PBSUtils.roundDecimal(PBSUtils.getRandomDecimal(0.1, 10), 1) def bidRequest = BidRequest.getDefaultBidRequest(APP).tap { imp.first().video = Video.defaultVideo ext.prebid.floors = new ExtPrebidFloors(enforcement: new ExtPrebidPriceFloorEnforcement(bidAdjustment: true)) From a89d7520261023d02de7c7a8981e270cce978280 Mon Sep 17 00:00:00 2001 From: markiian Date: Fri, 10 Nov 2023 16:41:25 +0200 Subject: [PATCH 11/16] Remove unused import --- .../tests/pricefloors/PriceFloorsSignalingSpec.groovy | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy index cdffe6f51b2..c5eea7563aa 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy @@ -17,7 +17,6 @@ import org.prebid.server.functional.model.request.auction.Video import org.prebid.server.functional.model.response.auction.BidResponse import org.prebid.server.functional.model.response.auction.MediaType import org.prebid.server.functional.util.PBSUtils -import spock.lang.RepeatUntilFailure import static org.mockserver.model.HttpStatusCode.BAD_REQUEST_400 import static org.prebid.server.functional.model.Currency.USD @@ -411,7 +410,6 @@ class PriceFloorsSignalingSpec extends PriceFloorsBaseSpec { true | null | false } - @RepeatUntilFailure def "PBS should choose most aggressive adjustment when request contains multiple media-types"() { given: "BidRequest with bidAdjustment" def bidAdjustment = PBSUtils.roundDecimal(PBSUtils.getRandomDecimal(0.1, 10), 1) From a8c531719aa52924cc21e31b37b368c442815fc7 Mon Sep 17 00:00:00 2001 From: markiian Date: Mon, 11 Dec 2023 13:11:19 +0200 Subject: [PATCH 12/16] Update naming --- .../org/prebid/server/functional/tests/CookieSyncSpec.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index b48b3eebd32..c6b9632633f 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -2119,7 +2119,7 @@ class CookieSyncSpec extends BaseSpec { when: "PBS processes cookie sync request" def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) - then: "Response should contain corresponding bidders size due to global config" + then: "Response should contain corresponding bidders size due to request limit" assert response.bidderStatus.size() == cookieSyncRequest.limit } From c9aaa16a9d0797177556a45b32e2b81347964722 Mon Sep 17 00:00:00 2001 From: markiian Date: Wed, 13 Dec 2023 16:25:58 +0200 Subject: [PATCH 13/16] Update after review --- .../functional/tests/CookieSyncSpec.groovy | 91 ++++++++++--------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index c6b9632633f..84240ddd5ae 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -1,3 +1,4 @@ +//file:noinspection GroovyGStringKey package org.prebid.server.functional.tests import org.prebid.server.functional.model.AccountStatus @@ -19,6 +20,7 @@ import org.prebid.server.functional.util.HttpUtil import org.prebid.server.functional.util.PBSUtils import org.prebid.server.functional.util.privacy.CcpaConsent import org.prebid.server.functional.util.privacy.TcfConsent +import spock.lang.IgnoreRest import java.time.Instant @@ -82,9 +84,7 @@ class CookieSyncSpec extends BaseSpec { "adapters.${APPNEXUS.value}.enabled" : "true", "adapters.${APPNEXUS.value}.usersync.cookie-family-name" : APPNEXUS.value, "adapters.${APPNEXUS.value}.usersync.redirect.url" : "https://test.appnexus.redirect.com/getuid?{{redirect_url}}", - "adapters.${APPNEXUS.value}.usersync.redirect.support-cors": CORS_SUPPORT as String, - "adapters.${APPNEXUS.value}.usersync.iframe.url" : "https://test.iframe.endpoint.com", - "adapters.${APPNEXUS.value}.usersync.iframe.support-cors" : CORS_SUPPORT as String] + "adapters.${APPNEXUS.value}.usersync.redirect.support-cors": CORS_SUPPORT as String] private static final Map AAX_CONFIG = ["adapters.${AAX.value}.enabled": "true"] private static final Map ACUITYADS_CONFIG = ["adapters.${ACUITYADS.value}.enabled": "true"] private static final Map ADKERNEL_CONFIG = ["adapters.${ADKERNEL.value}.enabled": "true"] @@ -1433,19 +1433,20 @@ class CookieSyncSpec extends BaseSpec { assert response.bidderStatus.bidder.containsAll(ADKERNEL, ACUITYADS, ACEEX, APPNEXUS, AAX, RUBICON, OPENX, GENERIC) } - def "PBS cookie sync request should filter bidder due to filterSettings"() { - given: "Empty cookie sync request body" + def "PBS cookie sync request should return bidder"() { + given: "Cookie sync request with filter setting" def filterSettings = new FilterSettings().tap { - iframe = new MethodFilter().tap { - filter = INCLUDE - bidders = [RUBICON, GENERIC] - } image = new MethodFilter().tap { filter = EXCLUDE - bidders = [APPNEXUS, OPENX] + bidders = [APPNEXUS] } } - def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) + def cookieSyncRequest = new CookieSyncRequest().tap { + it.filterSettings = filterSettings + it.limit = 0 + it.coopSync = false + it.debug = true + } when: "PBS processes cookie sync request without cookies" def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) @@ -1453,16 +1454,12 @@ class CookieSyncSpec extends BaseSpec { then: "Response should have status 'NO_COOKIE'" assert response.status == NO_COOKIE - and: "Bidder should be exclude by filter" - def rubiconUserSync = response.getBidderUserSync(RUBICON) - assert rubiconUserSync?.userSync?.type == IFRAME - - and: "Bidder shouldn't be include by filter" + and: "Bidder should be excluded by filter" assert !response.getBidderUserSync(APPNEXUS) } def "PBS cookie sync request should include all bidder due to filterSettings"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with filter setting" def filterSettings = new FilterSettings().tap { iframe = new MethodFilter(bidders: [RUBICON], filter: INCLUDE) image = new MethodFilter(bidders: [APPNEXUS], filter: INCLUDE) @@ -1481,7 +1478,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request should exclude all iframe bidders when asterisk present in bidders filterSettings"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with filter setting" def filterSettings = new FilterSettings().tap { iframe = new MethodFilter(bidders: ALL_BIDDERS, filter: EXCLUDE) } @@ -1501,7 +1498,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request should exclude all image bidders when asterisk present in bidders filterSettings"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with filter setting" def filterSettings = new FilterSettings().tap { image = new MethodFilter(bidders: ALL_BIDDERS, filter: EXCLUDE) } @@ -1521,7 +1518,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request shouldn't include bidder with invalid user sync type"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with filter setting" def filterSettings = new FilterSettings().tap { iframe = new MethodFilter(bidders: [GENERIC], filter: INCLUDE) } @@ -1539,7 +1536,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request shouldn't exclude bidder with invalid user sync type"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with filter setting" def filterSettings = new FilterSettings().tap { iframe = new MethodFilter(bidders: [GENERIC], filter: EXCLUDE) } @@ -1557,7 +1554,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request should ignore iframe invalid bidder in method filter bidders"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with filter setting" def filterSettings = new FilterSettings().tap { iframe = new MethodFilter(bidders: [bidders], filter: INCLUDE) } @@ -1577,7 +1574,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request should ignore image invalid bidder in method filter bidders"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with filter setting" def filterSettings = new FilterSettings().tap { image = new MethodFilter(bidders: [bidders], filter: INCLUDE) } @@ -1597,7 +1594,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request should successfully passed when account is absent"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with filter setting" def cookieSyncRequest = new CookieSyncRequest(account: null) when: "PBS processes cookie sync request without cookies" @@ -1612,7 +1609,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request should return url for all bidders when no uids cookie is present"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with empty account" def cookieSyncRequest = new CookieSyncRequest(account: null) when: "PBS processes cookie sync request without cookies" @@ -1650,7 +1647,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request shouldn't return iframe sync url included by sync type bidders for bidder in cookie"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with filter setting" def filterSettings = new FilterSettings().tap { iframe = new MethodFilter(bidders: [GENERIC], filter: INCLUDE) } @@ -1667,7 +1664,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request shouldn't return image sync url included by sync type bidders for bidder in cookie"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with filter setting" def filterSettings = new FilterSettings().tap { image = new MethodFilter(bidders: [APPNEXUS], filter: INCLUDE) } @@ -1687,7 +1684,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request shouldn't return requested bidder when bidders present in uids cookie"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with generic bidders" def cookieSyncRequest = new CookieSyncRequest(bidders: [GENERIC]) and: "Set up generic uids cookie" @@ -1704,7 +1701,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request should return all possible bidder"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with non specified bidders and specified coop sync" def cookieSyncRequest = new CookieSyncRequest(bidders: null, coopSync: true) when: "PBS processes cookie sync request" @@ -1896,6 +1893,7 @@ class CookieSyncSpec extends BaseSpec { assert response.getBidderStatus().size() == cookieSyncRequest.limit } + @IgnoreRest def "PBS cookie sync request should return bidders matched in bidders and filter settings"() { given: "Cookie sync request body" def cookieSyncRequest = new CookieSyncRequest().tap { @@ -1910,11 +1908,11 @@ class CookieSyncSpec extends BaseSpec { then: "Response should contains the same size" assert response.bidderStatus.bidder.size() == cookieSyncRequest.bidders.size() - and: "" + and: "Should contain requested bidders" assert response.bidderStatus.bidder.containsAll(GENERIC, RUBICON) } - def "PBS cookie sync request should return maximum 8 coop sync bidder when limit is not specified"() { + def "PBS cookie sync request should fill response with 8 coop sync bidder when limit is not specified"() { given: "Cookie sync request body" def cookieSyncRequest = new CookieSyncRequest().tap { it.coopSync = true @@ -1925,7 +1923,7 @@ class CookieSyncSpec extends BaseSpec { def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) then: "Response should contains 8 coop sync bidders" - assert response.bidderStatus.bidder.size() == 8 + assert response.bidderStatus.bidder.size() == DEFAULT_PBS_BIDDERS_SIZE } def "PBS cookie sync request should override general configuration limit"() { @@ -1962,7 +1960,7 @@ class CookieSyncSpec extends BaseSpec { assert response.getBidderUserSync(RUBICON) } - def "PBS cookie sync request shouldn't include bidder if this bidder in uids cookie"() { + def "PBS cookie sync request shouldn't include bidder when bidder specified in uids cookie"() { given: "Cookie sync request body" def cookieSyncRequest = new CookieSyncRequest().tap { coopSync = false @@ -1977,8 +1975,11 @@ class CookieSyncSpec extends BaseSpec { when: "PBS processes cookie sync request with cookies" def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest, cookie) - then: "Response should contain error" + then: "Response should contain valid bidder" assert response.getBidderUserSync(RUBICON) + + and: "Response shouldn't contain bidder that present in uids cookie" + assert !response.getBidderUserSync(APPNEXUS) } def "PBS cookie sync request shouldn't limit bidders with zero value in config"() { @@ -1999,7 +2000,7 @@ class CookieSyncSpec extends BaseSpec { def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) then: "Response should contain valid bidder status" - assert response.bidderStatus.size() == 2 + assert response.bidderStatus.size() == cookieSyncRequest.bidders.size() } def "PBS cookie sync request should max limit override default limit"() { @@ -2012,7 +2013,8 @@ class CookieSyncSpec extends BaseSpec { } and: "Save account with cookie config" - def cookieSyncConfig = new AccountCookieSyncConfig(maxLimit: 1, defaultLimit: 2) + def maxLimit = 1 + def cookieSyncConfig = new AccountCookieSyncConfig(maxLimit: maxLimit, defaultLimit: 2) def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) def account = new Account(uuid: accountId, config: accountConfig) accountDao.save(account) @@ -2021,7 +2023,7 @@ class CookieSyncSpec extends BaseSpec { def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) then: "Response should contain corresponding bidders size due to config" - assert response.bidderStatus.size() == 1 + assert response.bidderStatus.size() == maxLimit } def "PBS cookie sync request should max limit in account take precedence over request limit"() { @@ -2035,7 +2037,8 @@ class CookieSyncSpec extends BaseSpec { } and: "Save account with cookie config" - def cookieSyncConfig = new AccountCookieSyncConfig(maxLimit: 1) + def maxLimit = 1 + def cookieSyncConfig = new AccountCookieSyncConfig(maxLimit: maxLimit) def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) def account = new Account(uuid: accountId, config: accountConfig) accountDao.save(account) @@ -2044,7 +2047,7 @@ class CookieSyncSpec extends BaseSpec { def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) then: "Response should contain corresponding bidders size due to config" - assert response.bidderStatus.size() == 1 + assert response.bidderStatus.size() == maxLimit } def "PBS cookie sync request should capped to max limit"() { @@ -2058,7 +2061,8 @@ class CookieSyncSpec extends BaseSpec { } and: "Save account with cookie config" - def cookieSyncConfig = new AccountCookieSyncConfig(maxLimit: 1) + def maxLimit = 1 + def cookieSyncConfig = new AccountCookieSyncConfig(maxLimit: maxLimit) def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) def account = new Account(uuid: accountId, config: accountConfig) accountDao.save(account) @@ -2067,7 +2071,7 @@ class CookieSyncSpec extends BaseSpec { def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) then: "Response should contain corresponding bidders size due to config" - assert response.bidderStatus.size() == 1 + assert response.bidderStatus.size() == maxLimit where: limitRequest << [0, 2, null] @@ -2084,7 +2088,8 @@ class CookieSyncSpec extends BaseSpec { } and: "Save account with cookie config" - def cookieSyncConfig = new AccountCookieSyncConfig(defaultLimit: 1) + def defaultLimit + def cookieSyncConfig = new AccountCookieSyncConfig(defaultLimit: defaultLimit) def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) def account = new Account(uuid: accountId, config: accountConfig) accountDao.save(account) @@ -2093,7 +2098,7 @@ class CookieSyncSpec extends BaseSpec { def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) then: "Response should contain corresponding bidders size due to config" - assert response.bidderStatus.size() == 1 + assert response.bidderStatus.size() == defaultLimit } def "PBS cookie sync request should take precedence request limit over account and global config"() { From 8258f8d88351f8ebf098dd7db1be3f5ce7f823d4 Mon Sep 17 00:00:00 2001 From: markiian Date: Wed, 13 Dec 2023 16:29:12 +0200 Subject: [PATCH 14/16] Remove unnecessary annotation --- .../org/prebid/server/functional/tests/CookieSyncSpec.groovy | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index 84240ddd5ae..f917d70f01e 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -20,7 +20,6 @@ import org.prebid.server.functional.util.HttpUtil import org.prebid.server.functional.util.PBSUtils import org.prebid.server.functional.util.privacy.CcpaConsent import org.prebid.server.functional.util.privacy.TcfConsent -import spock.lang.IgnoreRest import java.time.Instant @@ -1893,7 +1892,6 @@ class CookieSyncSpec extends BaseSpec { assert response.getBidderStatus().size() == cookieSyncRequest.limit } - @IgnoreRest def "PBS cookie sync request should return bidders matched in bidders and filter settings"() { given: "Cookie sync request body" def cookieSyncRequest = new CookieSyncRequest().tap { From 86bbb24dd150859c0e016a7903f45fbbb71bd374 Mon Sep 17 00:00:00 2001 From: markiian Date: Thu, 14 Dec 2023 18:02:08 +0200 Subject: [PATCH 15/16] Minor update --- .../org/prebid/server/functional/tests/CookieSyncSpec.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index f917d70f01e..a39376d5c41 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -2086,7 +2086,7 @@ class CookieSyncSpec extends BaseSpec { } and: "Save account with cookie config" - def defaultLimit + def defaultLimit = 1 def cookieSyncConfig = new AccountCookieSyncConfig(defaultLimit: defaultLimit) def accountConfig = new AccountConfig(status: AccountStatus.ACTIVE, cookieSync: cookieSyncConfig) def account = new Account(uuid: accountId, config: accountConfig) From 88267301cb470c26d3b1a308a85f71134f3d8e9c Mon Sep 17 00:00:00 2001 From: markiian Date: Mon, 18 Dec 2023 16:07:58 +0200 Subject: [PATCH 16/16] Update after review --- .../functional/tests/CookieSyncSpec.groovy | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index a39376d5c41..28b6ac5a591 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -1489,9 +1489,6 @@ class CookieSyncSpec extends BaseSpec { then: "Response should have status 'NO_COOKIE'" assert response.status == NO_COOKIE - and: "Response shouldn't contains bidders with IFRAME" - assert response?.bidderStatus?.every { it.getUserSync().type != IFRAME } - and: "Response should contain only bidders with IMAGE" assert response?.bidderStatus?.every { it.getUserSync().type == REDIRECT } } @@ -1511,9 +1508,6 @@ class CookieSyncSpec extends BaseSpec { and: "Response should contains all bidders with IFRAME" assert response?.bidderStatus?.every { it.getUserSync().type == IFRAME } - - and: "Response shouldn't contain bidders with IMAGE" - assert response?.bidderStatus?.every { it.getUserSync().type != REDIRECT } } def "PBS cookie sync request shouldn't include bidder with invalid user sync type"() { @@ -1593,7 +1587,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request should successfully passed when account is absent"() { - given: "Cookie sync request with filter setting" + given: "Cookie sync request with empty account" def cookieSyncRequest = new CookieSyncRequest(account: null) when: "PBS processes cookie sync request without cookies" @@ -1609,7 +1603,7 @@ class CookieSyncSpec extends BaseSpec { def "PBS cookie sync request should return url for all bidders when no uids cookie is present"() { given: "Cookie sync request with empty account" - def cookieSyncRequest = new CookieSyncRequest(account: null) + def cookieSyncRequest = new CookieSyncRequest() when: "PBS processes cookie sync request without cookies" def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) @@ -1652,8 +1646,11 @@ class CookieSyncSpec extends BaseSpec { } def cookieSyncRequest = new CookieSyncRequest(filterSettings: filterSettings, limit: 0) - when: "PBS processes cookie sync request with generic uid cookies" - def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest, UidsCookie.defaultUidsCookie) + and: "Set up uids cookie" + def uidsCookie = UidsCookie.defaultUidsCookie + + when: "PBS processes cookie sync request with uids cookies" + def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest, uidsCookie) then: "Response should have status 'OK'" assert response.status == OK @@ -1709,10 +1706,16 @@ class CookieSyncSpec extends BaseSpec { then: "Response should have status 'NO_COOKIE'" assert response.status == NO_COOKIE - and: "Response should contain coop sync bidder" + and: "Response should contain coop sync bidders" + assert response.bidderStatus.size() == DEFAULT_PBS_BIDDERS_SIZE assert response.getBidderUserSync(AAX) assert response.getBidderUserSync(ACUITYADS) assert response.getBidderUserSync(ADKERNEL) + assert response.getBidderUserSync(OPENX) + assert response.getBidderUserSync(GENERIC) + assert response.getBidderUserSync(APPNEXUS) + assert response.getBidderUserSync(RUBICON) + assert response.getBidderUserSync(ACEEX) } def "PBS cookie sync request should contain request bidders and rest from coop sync"() { @@ -1810,7 +1813,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request shouldn't return any bidder when coop sync off and bidder is invalid"() { - given: "Empty cookie sync request body" + given: "Cookie sync request body with bidders and disabled coop-sync" def cookieSyncRequest = new CookieSyncRequest(coopSync: false, bidders: givenBidder) when: "PBS processes cookie sync request without cookies" @@ -1827,7 +1830,7 @@ class CookieSyncSpec extends BaseSpec { } def "PBS cookie sync request shouldn't return all bidders when coop sync #coopSync and limit param specified"() { - given: "Empty cookie sync request body" + given: "Cookie sync request with bidders and limit" def cookieSyncRequest = new CookieSyncRequest(coopSync: coopSync, bidders: [APPNEXUS, RUBICON], limit: 1) when: "PBS processes cookie sync request without cookies" @@ -1910,7 +1913,7 @@ class CookieSyncSpec extends BaseSpec { assert response.bidderStatus.bidder.containsAll(GENERIC, RUBICON) } - def "PBS cookie sync request should fill response with 8 coop sync bidder when limit is not specified"() { + def "PBS cookie sync request should fill response with all available coop sync bidder when limit is not specified"() { given: "Cookie sync request body" def cookieSyncRequest = new CookieSyncRequest().tap { it.coopSync = true @@ -1920,7 +1923,7 @@ class CookieSyncSpec extends BaseSpec { when: "PBS processes cookie sync request without cookies" def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) - then: "Response should contains 8 coop sync bidders" + then: "Response should contains all available coop sync bidders" assert response.bidderStatus.bidder.size() == DEFAULT_PBS_BIDDERS_SIZE } @@ -1928,14 +1931,14 @@ class CookieSyncSpec extends BaseSpec { given: "Cookie sync request body" def cookieSyncRequest = new CookieSyncRequest().tap { it.coopSync = true - it.limit = 4 + it.limit = PBSUtils.getRandomNumber(1, DEFAULT_PBS_BIDDERS_SIZE) } when: "PBS processes cookie sync request without cookies" def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest) - then: "Response should contains 4 coop sync bidders" - assert response.bidderStatus.bidder.size() == cookieSyncRequest.limit + then: "Response should contains same count of bidder as specified limit" + assert response.bidderStatus.size() == cookieSyncRequest.limit } def "PBS cookie sync request should return bidders without excluded by filter settings"() {