Skip to content

Commit

Permalink
GPP4.5: Functional tests for custom logic functionality (#2494)
Browse files Browse the repository at this point in the history
  • Loading branch information
osulzhenko authored Sep 20, 2023
1 parent b52c398 commit 7e66a92
Show file tree
Hide file tree
Showing 22 changed files with 2,682 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.prebid.server.functional.model.config

import groovy.transform.ToString
import org.prebid.server.functional.model.request.auction.ActivityType

import static org.prebid.server.functional.model.config.DataActivity.INVALID
import static org.prebid.server.functional.model.config.LogicalRestrictedRule.LogicalOperation.OR
import static org.prebid.server.functional.model.config.UsNationalPrivacySection.GPC

@ToString(includeNames = true, ignoreNulls = true)
class ActivityConfig {

List<ActivityType> activities
LogicalRestrictedRule restrictIfTrue

ActivityConfig() {
}

ActivityConfig(List<ActivityType> activities, LogicalRestrictedRule restrictIfTrue) {
this.activities = activities
this.restrictIfTrue = restrictIfTrue
}

static ActivityConfig getConfigWithDefaultRestrictRules(List<ActivityType> activities = ActivityType.values()) {
new ActivityConfig().tap {
it.activities = activities
it.restrictIfTrue = LogicalRestrictedRule.generateSingleRestrictedRule(OR, [new InequalityValueRule(GPC, INVALID)])
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.prebid.server.functional.model.config

import com.fasterxml.jackson.annotation.JsonValue

enum DataActivity {

NOT_APPLICABLE(0),
NOTICE_PROVIDED(1),
NOTICE_NOT_PROVIDED(2),
NO_CONSENT(1),
CONSENT(2),
INVALID(-1),

@JsonValue
final int dataActivityBits

DataActivity(int dataActivityBits) {
this.dataActivityBits = dataActivityBits
}

static DataActivity fromInt(int dataActivityBits) {
values().find { it.dataActivityBits == dataActivityBits }
?: { throw new IllegalArgumentException("Invalid dataActivityBits: ${dataActivityBits}") }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.prebid.server.functional.model.config

import com.fasterxml.jackson.core.JacksonException
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import groovy.transform.ToString

@ToString(includeNames = true, ignoreNulls = true)
@JsonDeserialize(using = EqualityValueRuleDeserialize.class)
class EqualityValueRule extends ValueRestrictedRule {

EqualityValueRule(UsNationalPrivacySection privacySection, DataActivity value) {
super(privacySection, value)
}

static class EqualityValueRuleDeserialize extends JsonDeserializer<EqualityValueRule> {

@Override
EqualityValueRule deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser)
def privacySection = UsNationalPrivacySection.valueFromText(node?.get(0)?.get(JSON_LOGIC_VALUE_FIELD)?.textValue())
def value = DataActivity.fromInt(node?.get(1)?.asInt())
return new EqualityValueRule(privacySection, value)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.prebid.server.functional.model.config

import com.fasterxml.jackson.core.JacksonException
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import groovy.transform.ToString

@ToString(includeNames = true, ignoreNulls = true)
@JsonDeserialize(using = InequalityValueRuleDeserialize.class)
class InequalityValueRule extends ValueRestrictedRule {

InequalityValueRule(UsNationalPrivacySection privacySection, DataActivity value) {
super(privacySection, value)
}

static class InequalityValueRuleDeserialize extends JsonDeserializer<InequalityValueRule> {

@Override
InequalityValueRule deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser)
def privacySection = UsNationalPrivacySection.valueFromText(node?.get(0)?.get(JSON_LOGIC_VALUE_FIELD)?.textValue())
def value = DataActivity.fromInt(node?.get(1)?.asInt())
return new InequalityValueRule(privacySection, value)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.prebid.server.functional.model.config

import com.fasterxml.jackson.annotation.JsonProperty
import groovy.transform.ToString

@ToString(includeNames = false, ignoreNulls = true)
class LogicalRestrictedRule {

@JsonProperty("==")
EqualityValueRule equalityRule

@JsonProperty("!=")
InequalityValueRule inequalityRule

List<LogicalRestrictedRule> or
List<LogicalRestrictedRule> and

LogicalRestrictedRule(ValueRestrictedRule valueOperation) {
if (valueOperation instanceof EqualityValueRule) {
equalityRule = valueOperation
} else if (valueOperation instanceof InequalityValueRule) {
inequalityRule = valueOperation
}
}

private LogicalRestrictedRule() {
}

static getRootLogicalRestricted() {
new LogicalRestrictedRule()
}

static LogicalRestrictedRule generateSingleRestrictedRule(LogicalOperation logicalOperator, List<ValueRestrictedRule> valueOperations) {
valueOperations.inject(new LogicalRestrictedRule()) { logicalRestrictedRule, value ->
logicalRestrictedRule.includeSubRestriction(logicalOperator, value)
logicalRestrictedRule
}
}

LogicalRestrictedRule includeSubRestriction(LogicalOperation logicalOperation, LogicalRestrictedRule logicalRestrictedRule) {
if (logicalOperation == LogicalOperation.OR) {
or = (or ?: []) + logicalRestrictedRule
} else if (logicalOperation == LogicalOperation.AND) {
and = (and ?: []) + logicalRestrictedRule
}
this
}

LogicalRestrictedRule includeSubRestriction(LogicalOperation logicalOperation, ValueRestrictedRule valueOperation) {
includeSubRestriction(logicalOperation, new LogicalRestrictedRule(valueOperation))
}

enum LogicalOperation {
OR, AND
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import org.prebid.server.functional.model.request.GppSectionId
@ToString(includeNames = true, ignoreNulls = true)
class ModuleConfig {

List<ActivityConfig> activityConfig
List<GppSectionId> sids
Boolean normalizeFlags

static ModuleConfig getDefaultModuleConfig(List<GppSectionId> sids = [GppSectionId.USP_NAT_V1],
static ModuleConfig getDefaultModuleConfig(ActivityConfig activityConfig = ActivityConfig.configWithDefaultRestrictRules,
List<GppSectionId> sids = [GppSectionId.USP_NAT_V1],
Boolean normalizeFlags = true) {
new ModuleConfig().tap {
it.activityConfig = [activityConfig]
it.sids = sids
it.normalizeFlags = normalizeFlags
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.prebid.server.functional.model.config

import com.fasterxml.jackson.annotation.JsonValue
import com.iab.gpp.encoder.field.UspNatV1Field
import org.prebid.server.functional.util.PBSUtils

enum UsNationalPrivacySection {

SHARING_NOTICE(UspNatV1Field.SHARING_NOTICE),
SALE_OPT_OUT_NOTICE(UspNatV1Field.SALE_OPT_OUT_NOTICE),
SHARING_OPT_OUT_NOTICE(UspNatV1Field.SHARING_OPT_OUT_NOTICE),
TARGETED_ADVERTISING_OPT_OUT_NOTICE(UspNatV1Field.TARGETED_ADVERTISING_OPT_OUT_NOTICE),
SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE(UspNatV1Field.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE),
SENSITIVE_DATA_LIMIT_USE_NOTICE(UspNatV1Field.SENSITIVE_DATA_LIMIT_USE_NOTICE),
SALE_OPT_OUT(UspNatV1Field.SALE_OPT_OUT),
SHARING_OPT_OUT(UspNatV1Field.SHARING_OPT_OUT),
TARGETED_ADVERTISING_OPT_OUT(UspNatV1Field.TARGETED_ADVERTISING_OPT_OUT),
SENSITIVE_DATA_RACIAL_ETHNIC_ORIGIN(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 1),
SENSITIVE_DATA_RELIGIOUS_BELIEFS(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 2),
SENSITIVE_DATA_HEALTH_INFO(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 3),
SENSITIVE_DATA_ORIENTATION(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 4),
SENSITIVE_DATA_CITIZENSHIP_STATUS(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 5),
SENSITIVE_DATA_GENETIC_ID(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 6),
SENSITIVE_DATA_BIOMETRIC_ID(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 7),
SENSITIVE_DATA_GEOLOCATION(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 8),
SENSITIVE_DATA_ID_NUMBERS(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 9),
SENSITIVE_DATA_ACCOUNT_INFO(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 10),
SENSITIVE_DATA_UNION_MEMBERSHIP(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 11),
SENSITIVE_DATA_COMMUNICATION_CONTENTS(UspNatV1Field.SENSITIVE_DATA_PROCESSING + 12),
SENSITIVE_DATA_PROCESSING_ALL(UspNatV1Field.SENSITIVE_DATA_PROCESSING + "*"),
CHILD_CONSENTS_FROM_13_TO_16(UspNatV1Field.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS + 1),
CHILD_CONSENTS_BELOW_13(UspNatV1Field.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS + 2),
PERSONAL_DATA_CONSENTS(UspNatV1Field.PERSONAL_DATA_CONSENTS),
MSPA_COVERED_TRANSACTION(UspNatV1Field.MSPA_COVERED_TRANSACTION),
MSPA_OPT_OUT_OPTION_MODE(UspNatV1Field.MSPA_OPT_OUT_OPTION_MODE),
MSPA_SERVICE_PROVIDER_MODE(UspNatV1Field.MSPA_SERVICE_PROVIDER_MODE),
GPC(UspNatV1Field.GPC);

@JsonValue
final String value

private UsNationalPrivacySection(String value) {
this.value = value
}

static UsNationalPrivacySection valueFromText(String value) {
values().find { section -> section.value.equalsIgnoreCase(value) }
?: { throw new IllegalArgumentException("Invalid UsNationalPrivacySection value: $value") }()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.prebid.server.functional.model.config

import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import groovy.transform.ToString

@ToString(includeNames = true, ignoreNulls = true)
@JsonSerialize(using = ValueRestrictedRuleSerializer.class)
@JsonIgnoreProperties(ignoreUnknown = true)
abstract class ValueRestrictedRule {

protected UsNationalPrivacySection privacySection
protected DataActivity value

protected static final String JSON_LOGIC_VALUE_FIELD = "var"

ValueRestrictedRule(UsNationalPrivacySection privacySection, DataActivity dataActivity) {
this.privacySection = privacySection
this.value = dataActivity
}

static class ValueRestrictedRuleSerializer extends JsonSerializer<ValueRestrictedRule> {

@Override
void serialize(ValueRestrictedRule valueRestrictedRule, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartArray()
jsonGenerator.writeStartObject()
jsonGenerator.writeStringField(JSON_LOGIC_VALUE_FIELD, valueRestrictedRule.privacySection.value)
jsonGenerator.writeEndObject()
jsonGenerator.writeObject(valueRestrictedRule.value.dataActivityBits)
jsonGenerator.writeEndArray()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
package org.prebid.server.functional.model.request.auction

import com.fasterxml.jackson.annotation.JsonValue

enum ActivityType {

SYNC_USER, FETCH_BIDS, ENRICH_UFPD, REPORT_ANALYTICS, TRANSMIT_UFPD, TRANSMIT_PRECISE_GEO
SYNC_USER("syncUser"),
FETCH_BIDS("fetchBids"),
ENRICH_UFPD("enrichUfpd"),
REPORT_ANALYTICS("reportAnalytics"),
TRANSMIT_UFPD("transmitUfpd"),
TRANSMIT_PRECISE_GEO("transmitPreciseGeo")

@JsonValue
final String value

ActivityType(String value) {
this.value = value
}

String getMetricValue() {
name().toLowerCase()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ enum PrivacyModule {

IAB_TFC_EU("iab.tcfeu"),
IAB_US_GENERAL("iab.usgeneral"),
IAB_US_CUSTOM_LOGIC("iab.uscustomlogic"),
IAB_ALL("iab.*"),
CUSTOM_US_UTAH("custom.usutah"),
ALL("*")
Expand Down
Loading

0 comments on commit 7e66a92

Please sign in to comment.