Skip to content

Commit b51a17e

Browse files
authored
Tests: Bidder Usersync Skipwhen Config (#4028)
1 parent 86b98af commit b51a17e

File tree

1 file changed

+254
-2
lines changed

1 file changed

+254
-2
lines changed

src/test/groovy/org/prebid/server/functional/tests/privacy/GppCookieSyncSpec.groovy

Lines changed: 254 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package org.prebid.server.functional.tests.privacy
22

33
import io.netty.handler.codec.http.HttpResponseStatus
4+
import org.prebid.server.functional.model.config.AccountConfig
5+
import org.prebid.server.functional.model.config.AccountGdprConfig
6+
import org.prebid.server.functional.model.config.AccountPrivacyConfig
7+
import org.prebid.server.functional.model.config.PurposeConfig
8+
import org.prebid.server.functional.model.db.Account
9+
import org.prebid.server.functional.model.request.GppSectionId
410
import org.prebid.server.functional.model.request.cookiesync.CookieSyncRequest
511
import org.prebid.server.functional.model.response.cookiesync.UserSyncInfo
612
import org.prebid.server.functional.service.PrebidServerException
@@ -13,7 +19,10 @@ import org.prebid.server.functional.util.privacy.TcfConsent
1319
import org.prebid.server.functional.util.privacy.gpp.TcfEuV2Consent
1420
import org.prebid.server.functional.util.privacy.gpp.UsV1Consent
1521

22+
import static org.prebid.server.functional.model.bidder.BidderName.ALIAS
1623
import static org.prebid.server.functional.model.bidder.BidderName.GENERIC
24+
import static org.prebid.server.functional.model.config.Purpose.P1
25+
import static org.prebid.server.functional.model.config.PurposeEnforcement.NO
1726
import static org.prebid.server.functional.model.request.GppSectionId.TCF_EU_V2
1827
import static org.prebid.server.functional.model.request.GppSectionId.USP_V1
1928
import static org.prebid.server.functional.model.response.cookiesync.UserSyncInfo.Type.IFRAME
@@ -28,15 +37,26 @@ class GppCookieSyncSpec extends BaseSpec {
2837
private static final UserSyncInfo.Type USER_SYNC_TYPE = REDIRECT
2938
private static final boolean CORS_SUPPORT = false
3039
private static final String USER_SYNC_URL = "$networkServiceContainer.rootUri/generic-usersync"
40+
private static final GppSectionId FIRST_GPP_SECTION = PBSUtils.getRandomEnum(GppSectionId.class)
41+
private static final GppSectionId SECOND_GPP_SECTION = PBSUtils.getRandomEnum(GppSectionId.class, [FIRST_GPP_SECTION])
42+
3143
private static final Map<String, String> GENERIC_CONFIG = [
3244
"adapters.${GENERIC.value}.meta-info.vendor-id" : GENERIC_VENDOR_ID as String,
3345
"adapters.${GENERIC.value}.usersync.${USER_SYNC_TYPE.value}.url" : USER_SYNC_URL,
3446
"adapters.${GENERIC.value}.usersync.${USER_SYNC_TYPE.value}.support-cors": CORS_SUPPORT.toString()]
47+
private static final Map<String, String> GENERIC_WITH_SKIP_CONFIG = [
48+
"adapters.${GENERIC.value}.meta-info.vendor-id" : GENERIC_VENDOR_ID as String,
49+
"adapters.${GENERIC.value}.usersync.${USER_SYNC_TYPE.value}.url" : "$networkServiceContainer.rootUri/generic-usersync&redir={{redirect_url}}".toString(),
50+
"adapters.${GENERIC.value}.usersync.skipwhen.gdpr" : 'true',
51+
"adapters.${GENERIC.value}.usersync.skipwhen.gpp_sid" : "${FIRST_GPP_SECTION.value}, ${SECOND_GPP_SECTION.value}".toString(),
52+
"adapters.${GENERIC.value}.usersync.${USER_SYNC_TYPE.value}.support-cors": CORS_SUPPORT.toString()]
3553

3654
private static PrebidServerService prebidServerService = pbsServiceFactory.getService(GENERIC_CONFIG)
55+
private static PrebidServerService prebidServerServiceWithSkipConfig = pbsServiceFactory.getService(GENERIC_WITH_SKIP_CONFIG + GENERIC_ALIAS_CONFIG)
3756

3857
def cleanupSpec() {
3958
pbsServiceFactory.removeContainer(GENERIC_CONFIG)
59+
pbsServiceFactory.removeContainer(GENERIC_WITH_SKIP_CONFIG + GENERIC_ALIAS_CONFIG)
4060
}
4161

4262
def "PBS cookie sync request should set GDPR to 1 when gpp_sid contains 2"() {
@@ -171,8 +191,8 @@ class GppCookieSyncSpec extends BaseSpec {
171191
it.gpp = new TcfEuV2Consent.Builder().build()
172192
it.gdpr = null
173193
it.gdprConsent = new TcfConsent.Builder().setPurposesLITransparency(DEVICE_ACCESS)
174-
.setVendorLegitimateInterest([GENERIC_VENDOR_ID])
175-
.build()
194+
.setVendorLegitimateInterest([GENERIC_VENDOR_ID])
195+
.build()
176196
}
177197

178198
when: "PBS processes cookie sync request"
@@ -261,4 +281,236 @@ class GppCookieSyncSpec extends BaseSpec {
261281
where:
262282
userSyncFormat << [REDIRECT, IFRAME]
263283
}
284+
285+
def "PBS should emit proper error message when request contain gdpr config and global skip gdpr config for adapter"() {
286+
given: "Default CookieSyncRequest with gdpr config"
287+
def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap {
288+
it.gppSid = TCF_EU_V2.intValue
289+
it.gdpr = 1
290+
it.gdprConsent = new TcfConsent.Builder().build()
291+
}
292+
293+
when: "PBS processes cookie sync request"
294+
def response = prebidServerServiceWithSkipConfig.sendCookieSyncRequest(cookieSyncRequest)
295+
296+
then: "Response userSync url shouldn't contain cookies and userSync"
297+
def bidderStatus = response.getBidderUserSync(GENERIC)
298+
assert !bidderStatus.userSync
299+
assert !bidderStatus.noCookie
300+
301+
and: "Response should contain proper error message"
302+
assert bidderStatus.error == "Rejected by regulation scope"
303+
}
304+
305+
def "PBS should emit proper error message when alias request contain gdpr config and global skip gdpr config for adapter"() {
306+
given: "Default CookieSyncRequest with gdpr config"
307+
def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap {
308+
it.bidders = [ALIAS]
309+
it.gppSid = TCF_EU_V2.intValue
310+
it.gdpr = 1
311+
it.gdprConsent = new TcfConsent.Builder().build()
312+
}
313+
314+
when: "PBS processes cookie sync request"
315+
def response = prebidServerServiceWithSkipConfig.sendCookieSyncRequest(cookieSyncRequest)
316+
317+
then: "Response userSync url shouldn't contain cookies and userSync"
318+
def bidderStatus = response.getBidderUserSync(GENERIC)
319+
assert !bidderStatus.userSync
320+
assert !bidderStatus.noCookie
321+
322+
and: "Response should contain proper error message"
323+
assert bidderStatus.error == "Rejected by regulation scope"
324+
}
325+
326+
def "PBS should emit proper error message when request contain gpp config and specific global skip gpp config for adapter"() {
327+
given: "Default CookieSyncRequest with gpp and gppSid"
328+
def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap {
329+
it.gppSid = TCF_EU_V2.intValue
330+
it.gpp = new UsV1Consent.Builder().build()
331+
it.gppSid = gppSid
332+
}
333+
334+
when: "PBS processes cookie sync request"
335+
def response = prebidServerServiceWithSkipConfig.sendCookieSyncRequest(cookieSyncRequest)
336+
337+
then: "Response userSync url shouldn't contain cookies and userSync"
338+
def bidderStatus = response.getBidderUserSync(GENERIC)
339+
assert !bidderStatus.userSync
340+
assert !bidderStatus.noCookie
341+
342+
and: "Response should contain proper error message"
343+
assert bidderStatus.error == "Rejected by regulation scope"
344+
345+
where:
346+
gppSid << ["${FIRST_GPP_SECTION.value}",
347+
"${SECOND_GPP_SECTION.value}",
348+
"${FIRST_GPP_SECTION.value}, ${SECOND_GPP_SECTION.value}",
349+
"${SECOND_GPP_SECTION.value}, ${FIRST_GPP_SECTION.value}",
350+
"${SECOND_GPP_SECTION.value}, ${FIRST_GPP_SECTION.value}",
351+
"${PBSUtils.getRandomEnum(GppSectionId.class, [FIRST_GPP_SECTION, SECOND_GPP_SECTION]).value}, ${SECOND_GPP_SECTION.value}",
352+
"${FIRST_GPP_SECTION.value}, ${PBSUtils.getRandomEnum(GppSectionId.class, [FIRST_GPP_SECTION, SECOND_GPP_SECTION]).value}"
353+
]
354+
}
355+
356+
def "PBS should emit proper error message when alias request contain gpp config and specific global skip gpp config for adapter"() {
357+
given: "Default CookieSyncRequest with gpp and gppSid"
358+
def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap {
359+
it.gppSid = TCF_EU_V2.intValue
360+
it.bidders = [ALIAS]
361+
it.gpp = new UsV1Consent.Builder().build()
362+
it.gppSid = gppSid
363+
}
364+
365+
when: "PBS processes cookie sync request"
366+
def response = prebidServerServiceWithSkipConfig.sendCookieSyncRequest(cookieSyncRequest)
367+
368+
then: "Response userSync url shouldn't contain cookies and userSync"
369+
def bidderStatus = response.getBidderUserSync(GENERIC)
370+
assert !bidderStatus.userSync
371+
assert !bidderStatus.noCookie
372+
373+
and: "Response should contain proper error message"
374+
assert bidderStatus.error == "Rejected by regulation scope"
375+
376+
where:
377+
gppSid << ["${FIRST_GPP_SECTION.value}",
378+
"${SECOND_GPP_SECTION.value}",
379+
"${FIRST_GPP_SECTION.value}, ${SECOND_GPP_SECTION.value}",
380+
"${SECOND_GPP_SECTION.value}, ${FIRST_GPP_SECTION.value}",
381+
"${SECOND_GPP_SECTION.value}, ${FIRST_GPP_SECTION.value}",
382+
"${PBSUtils.getRandomEnum(GppSectionId.class, [FIRST_GPP_SECTION, SECOND_GPP_SECTION]).value}, ${SECOND_GPP_SECTION.value}",
383+
"${FIRST_GPP_SECTION.value}, ${PBSUtils.getRandomEnum(GppSectionId.class, [FIRST_GPP_SECTION, SECOND_GPP_SECTION]).value}"
384+
]
385+
}
386+
387+
def "PBS shouldn't emit error message when request doesn't contain gdpr config and global skip gdpr config for adapter"() {
388+
given: "Default CookieSyncRequest with gdpr config"
389+
def gppSid = TCF_EU_V2
390+
def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap {
391+
it.gppSid = gppSid.intValue
392+
it.gdpr = 0
393+
it.gdprConsent = new TcfConsent.Builder().build()
394+
}
395+
396+
when: "PBS processes cookie sync request"
397+
def response = prebidServerServiceWithSkipConfig.sendCookieSyncRequest(cookieSyncRequest)
398+
399+
then: "Response userSync url should contain cookies and userSync"
400+
def bidderStatus = response.getBidderUserSync(GENERIC)
401+
assert HttpUtil.findUrlParameterValue(bidderStatus.userSync?.url, "gpp") == ""
402+
assert HttpUtil.findUrlParameterValue(bidderStatus.userSync?.url, "gpp_sid") == gppSid.value
403+
404+
and: "Response shouldn't contains any error"
405+
assert !bidderStatus.error
406+
}
407+
408+
def "PBS shouldn't emit error message when request does contain gdpr config and global skip gdpr config disabled for adapter"() {
409+
given: "Pbs config with usersync.#userSyncFormat.url"
410+
def pbsConfig = [
411+
"adapters.${GENERIC.value}.meta-info.vendor-id" : GENERIC_VENDOR_ID as String,
412+
"adapters.${GENERIC.value}.usersync.${USER_SYNC_TYPE.value}.url" : USER_SYNC_URL,
413+
"adapters.${GENERIC.value}.usersync.skipwhen.gdpr" : 'false',
414+
"adapters.${GENERIC.value}.usersync.${USER_SYNC_TYPE.value}.support-cors": CORS_SUPPORT.toString()]
415+
def prebidServerService = pbsServiceFactory.getService(pbsConfig)
416+
417+
and: "Default CookieSyncRequest with gdpr config"
418+
def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap {
419+
it.gppSid = TCF_EU_V2
420+
it.gdpr = 1
421+
it.gdprConsent = new TcfConsent.Builder().setPurposesLITransparency(DEVICE_ACCESS)
422+
.setVendorLegitimateInterest([GENERIC_VENDOR_ID])
423+
.build()
424+
it.account = PBSUtils.randomNumber
425+
}
426+
427+
and: "Save account config with requireConsent into DB"
428+
def purposes = [(P1): new PurposeConfig(enforcePurpose: NO, enforceVendors: false)]
429+
def accountGdprConfig = new AccountGdprConfig(purposes: purposes)
430+
def privacyConfig = new AccountPrivacyConfig(gdpr: accountGdprConfig)
431+
def account = new Account(uuid: cookieSyncRequest.account, config: new AccountConfig(privacy: privacyConfig))
432+
accountDao.save(account)
433+
434+
when: "PBS processes cookie sync request"
435+
def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest)
436+
437+
then: "Response should contain proper userSync url"
438+
def bidderStatus = response.getBidderUserSync(GENERIC)
439+
assert bidderStatus.userSync?.url == USER_SYNC_URL
440+
441+
and: "Response shouldn't contains any error"
442+
assert !bidderStatus.error
443+
444+
cleanup: "Stop and remove pbs container"
445+
pbsServiceFactory.removeContainer(pbsConfig)
446+
}
447+
448+
def "PBS shouldn't emit error message when request does contain gdpr config and global skip gdpr config default for adapter"() {
449+
given: "Default CookieSyncRequest with gdpr config"
450+
def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap {
451+
it.gppSid = TCF_EU_V2
452+
it.gdpr = 1
453+
it.gdprConsent = new TcfConsent.Builder().setPurposesLITransparency(DEVICE_ACCESS)
454+
.setVendorLegitimateInterest([GENERIC_VENDOR_ID])
455+
.build()
456+
it.account = PBSUtils.randomNumber
457+
}
458+
459+
and: "Save account config with requireConsent into DB"
460+
def purposes = [(P1): new PurposeConfig(enforcePurpose: NO, enforceVendors: false)]
461+
def accountGdprConfig = new AccountGdprConfig(purposes: purposes)
462+
def privacyConfig = new AccountPrivacyConfig(gdpr: accountGdprConfig)
463+
def account = new Account(uuid: cookieSyncRequest.account, config: new AccountConfig(privacy: privacyConfig))
464+
accountDao.save(account)
465+
466+
when: "PBS processes cookie sync request"
467+
def response = prebidServerService.sendCookieSyncRequest(cookieSyncRequest)
468+
469+
then: "Response should contain proper userSync url"
470+
def bidderStatus = response.getBidderUserSync(GENERIC)
471+
assert bidderStatus.userSync?.url == USER_SYNC_URL
472+
473+
and: "Response shouldn't contains any error"
474+
assert !bidderStatus.error
475+
}
476+
477+
def "PBS shouldn't emit error message when request doesn't contain matched gpp config and specific global skip gpp config for adapter"() {
478+
given: "Default CookieSyncRequest with gpp and gppSid"
479+
def gpp = new UsV1Consent.Builder().build()
480+
def gppSid = "${PBSUtils.getRandomEnum(GppSectionId.class, [FIRST_GPP_SECTION, SECOND_GPP_SECTION]).value}"
481+
def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap {
482+
it.gppSid = TCF_EU_V2.intValue
483+
it.gpp = gpp
484+
it.gppSid = gppSid
485+
}
486+
487+
when: "PBS processes cookie sync request"
488+
def response = prebidServerServiceWithSkipConfig.sendCookieSyncRequest(cookieSyncRequest)
489+
490+
then: "Response userSync url should contain gpp and gppSid"
491+
def bidderStatus = response.getBidderUserSync(GENERIC)
492+
assert HttpUtil.findUrlParameterValue(bidderStatus.userSync?.url, "gpp") == gpp.toString()
493+
assert HttpUtil.findUrlParameterValue(bidderStatus.userSync?.url, "gpp_sid") == gppSid
494+
495+
and: "Response shouldn't contains any error"
496+
assert !bidderStatus.error
497+
}
498+
499+
def "PBS should also include validation warning when request matches skip config and has validation issue at same time"() {
500+
def cookieSyncRequest = CookieSyncRequest.defaultCookieSyncRequest.tap {
501+
it.gppSid = PBSUtils.getRandomNumberWithExclusion(TCF_EU_V2.intValue)
502+
it.gdpr = 1
503+
it.gdprConsent = new TcfConsent.Builder().build()
504+
}
505+
506+
when: "PBS processes cookie sync request"
507+
def response = prebidServerServiceWithSkipConfig.sendCookieSyncRequest(cookieSyncRequest)
508+
509+
then: "Response should contain a warning"
510+
assert response.warnings == ["GPP scope does not match TCF2 scope"]
511+
512+
then: "Privacy for bidder should be enforced"
513+
def bidderStatus = response.getBidderUserSync(GENERIC)
514+
assert bidderStatus.error == "Rejected by regulation scope"
515+
}
264516
}

0 commit comments

Comments
 (0)