diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/alert/Action.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/alert/Action.groovy new file mode 100644 index 00000000000..8760760c00a --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/alert/Action.groovy @@ -0,0 +1,6 @@ +package org.prebid.server.functional.model.deals.alert + +enum Action { + + RAISE +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/alert/AlertEvent.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/alert/AlertEvent.groovy new file mode 100644 index 00000000000..596b7221c46 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/alert/AlertEvent.groovy @@ -0,0 +1,20 @@ +package org.prebid.server.functional.model.deals.alert + +import com.fasterxml.jackson.databind.PropertyNamingStrategies +import com.fasterxml.jackson.databind.annotation.JsonNaming +import groovy.transform.ToString + +import java.time.ZonedDateTime + +@ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy) +class AlertEvent { + + String id + Action action + AlertPriority priority + ZonedDateTime updatedAt + String name + String details + AlertSource source +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/alert/AlertPriority.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/alert/AlertPriority.groovy new file mode 100644 index 00000000000..502b2d5eb25 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/alert/AlertPriority.groovy @@ -0,0 +1,6 @@ +package org.prebid.server.functional.model.deals.alert + +enum AlertPriority { + + HIGH, MEDIUM, LOW +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/alert/AlertSource.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/alert/AlertSource.groovy new file mode 100644 index 00000000000..3175711c4be --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/alert/AlertSource.groovy @@ -0,0 +1,17 @@ +package org.prebid.server.functional.model.deals.alert + +import com.fasterxml.jackson.databind.PropertyNamingStrategies +import com.fasterxml.jackson.databind.annotation.JsonNaming +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy) +class AlertSource { + + String env + String dataCenter + String region + String system + String subSystem + String hostId +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/DeliverySchedule.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/DeliverySchedule.groovy new file mode 100644 index 00000000000..8b59632171b --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/DeliverySchedule.groovy @@ -0,0 +1,37 @@ +package org.prebid.server.functional.model.deals.lineitem + +import com.fasterxml.jackson.annotation.JsonFormat +import groovy.transform.ToString +import org.prebid.server.functional.util.PBSUtils + +import java.time.ZoneId +import java.time.ZonedDateTime + +import static java.time.ZoneOffset.UTC +import static org.prebid.server.functional.model.deals.lineitem.LineItem.TIME_PATTERN + +@ToString(includeNames = true, ignoreNulls = true) +class DeliverySchedule { + + String planId + + @JsonFormat(pattern = TIME_PATTERN) + ZonedDateTime startTimeStamp + + @JsonFormat(pattern = TIME_PATTERN) + ZonedDateTime endTimeStamp + + @JsonFormat(pattern = TIME_PATTERN) + ZonedDateTime updatedTimeStamp + + Set tokens + + static getDefaultDeliverySchedule() { + new DeliverySchedule(planId: PBSUtils.randomString, + startTimeStamp: ZonedDateTime.now(ZoneId.from(UTC)), + endTimeStamp: ZonedDateTime.now(ZoneId.from(UTC)).plusDays(1), + updatedTimeStamp: ZonedDateTime.now(ZoneId.from(UTC)), + tokens: [Token.defaultToken] + ) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/FrequencyCap.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/FrequencyCap.groovy new file mode 100644 index 00000000000..995ae1b9309 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/FrequencyCap.groovy @@ -0,0 +1,23 @@ +package org.prebid.server.functional.model.deals.lineitem + +import groovy.transform.ToString +import org.prebid.server.functional.util.PBSUtils + +import static PeriodType.DAY + +@ToString(includeNames = true, ignoreNulls = true) +class FrequencyCap { + + String fcapId + Integer count + Integer periods + String periodType + + static getDefaultFrequencyCap() { + new FrequencyCap(count: 1, + fcapId: PBSUtils.randomString, + periods: 1, + periodType: DAY + ) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/LineItem.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/LineItem.groovy new file mode 100644 index 00000000000..4f23c7e02ac --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/LineItem.groovy @@ -0,0 +1,74 @@ +package org.prebid.server.functional.model.deals.lineitem + +import com.fasterxml.jackson.annotation.JsonFormat +import groovy.transform.ToString +import org.prebid.server.functional.model.deals.lineitem.targeting.Targeting +import org.prebid.server.functional.util.PBSUtils + +import java.time.ZoneId +import java.time.ZonedDateTime + +import static Status.ACTIVE +import static java.time.ZoneOffset.UTC +import static org.prebid.server.functional.model.bidder.BidderName.GENERIC +import static org.prebid.server.functional.model.deals.lineitem.RelativePriority.VERY_HIGH + +@ToString(includeNames = true, ignoreNulls = true) +class LineItem { + + public static final String TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'" + + String lineItemId + + String extLineItemId + + String dealId + + List sizes + + String accountId + + String source + + Price price + + RelativePriority relativePriority + + @JsonFormat(pattern = TIME_PATTERN) + ZonedDateTime startTimeStamp + + @JsonFormat(pattern = TIME_PATTERN) + ZonedDateTime endTimeStamp + + @JsonFormat(pattern = TIME_PATTERN) + ZonedDateTime updatedTimeStamp + + Status status + + List frequencyCaps + + List deliverySchedules + + Targeting targeting + + static LineItem getDefaultLineItem(String accountId) { + int plannerAdapterLineItemId = PBSUtils.randomNumber + String plannerAdapterName = PBSUtils.randomString + new LineItem(lineItemId: "${plannerAdapterName}-$plannerAdapterLineItemId", + extLineItemId: plannerAdapterLineItemId, + dealId: PBSUtils.randomString, + sizes: [LineItemSize.defaultLineItemSize], + accountId: accountId, + source: GENERIC.name().toLowerCase(), + price: Price.defaultPrice, + relativePriority: VERY_HIGH, + startTimeStamp: ZonedDateTime.now(ZoneId.from(UTC)), + endTimeStamp: ZonedDateTime.now(ZoneId.from(UTC)).plusMonths(1), + updatedTimeStamp: ZonedDateTime.now(ZoneId.from(UTC)), + status: ACTIVE, + frequencyCaps: [], + deliverySchedules: [DeliverySchedule.defaultDeliverySchedule], + targeting: Targeting.defaultTargeting + ) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/LineItemSize.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/LineItemSize.groovy new file mode 100644 index 00000000000..c50b9fd4d58 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/LineItemSize.groovy @@ -0,0 +1,20 @@ +package org.prebid.server.functional.model.deals.lineitem + +import com.fasterxml.jackson.annotation.JsonInclude +import groovy.transform.ToString + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.ALWAYS + +@ToString(includeNames = true) +@JsonInclude(content = ALWAYS) +class LineItemSize { + + Integer w + Integer h + + static getDefaultLineItemSize() { + new LineItemSize(w: 300, + h: 250 + ) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/MediaType.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/MediaType.groovy new file mode 100644 index 00000000000..949da3d9b53 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/MediaType.groovy @@ -0,0 +1,20 @@ +package org.prebid.server.functional.model.deals.lineitem + +import com.fasterxml.jackson.annotation.JsonValue + +enum MediaType { + + BANNER("banner") + + @JsonValue + final String value + + private MediaType(String value) { + this.value = value + } + + @Override + String toString() { + value + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/PeriodType.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/PeriodType.groovy new file mode 100644 index 00000000000..10ca6f59d9c --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/PeriodType.groovy @@ -0,0 +1,24 @@ +package org.prebid.server.functional.model.deals.lineitem + +import com.fasterxml.jackson.annotation.JsonValue + +enum PeriodType { + + HOUR("hour"), + DAY("day"), + WEEK("week"), + MONTH("month"), + CAMPAIGN("campaign") + + @JsonValue + final String value + + private PeriodType(String value) { + this.value = value + } + + @Override + String toString() { + value + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/Price.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/Price.groovy new file mode 100644 index 00000000000..f74f10f8292 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/Price.groovy @@ -0,0 +1,16 @@ +package org.prebid.server.functional.model.deals.lineitem + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class Price { + + BigDecimal cpm + String currency + + static getDefaultPrice() { + new Price(cpm: 0.01, + currency: "USD" + ) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/RelativePriority.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/RelativePriority.groovy new file mode 100644 index 00000000000..911da0b365f --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/RelativePriority.groovy @@ -0,0 +1,24 @@ +package org.prebid.server.functional.model.deals.lineitem + +import com.fasterxml.jackson.annotation.JsonValue + +enum RelativePriority { + + VERY_HIGH(1), + HIGH(2), + MEDIUM(3), + LOW(4), + VERY_LOW(5) + + @JsonValue + final Integer value + + private RelativePriority(Integer value) { + this.value = value + } + + @Override + String toString() { + value + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/Status.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/Status.groovy new file mode 100644 index 00000000000..f6c5e5f884d --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/Status.groovy @@ -0,0 +1,22 @@ +package org.prebid.server.functional.model.deals.lineitem + +import com.fasterxml.jackson.annotation.JsonValue + +enum Status { + + ACTIVE("active"), + DELETED("deleted"), + PAUSED("paused") + + @JsonValue + final String value + + private Status(String value) { + this.value = value + } + + @Override + String toString() { + value + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/Token.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/Token.groovy new file mode 100644 index 00000000000..e7dd3f2fc5d --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/Token.groovy @@ -0,0 +1,19 @@ +package org.prebid.server.functional.model.deals.lineitem + +import com.fasterxml.jackson.annotation.JsonProperty +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class Token { + + @JsonProperty("class") + Integer priorityClass + + Integer total + + static getDefaultToken() { + new Token(priorityClass: 1, + total: 1000 + ) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/BooleanOperator.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/BooleanOperator.groovy new file mode 100644 index 00000000000..0e4a4740e53 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/BooleanOperator.groovy @@ -0,0 +1,20 @@ +package org.prebid.server.functional.model.deals.lineitem.targeting + +import com.fasterxml.jackson.annotation.JsonValue + +enum BooleanOperator { + + AND('$and'), + OR('$or'), + NOT('$not'), + + INVALID('$invalid'), + UPPERCASE_AND('$AND') + + @JsonValue + final String value + + private BooleanOperator(String value) { + this.value = value + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/MatchingFunction.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/MatchingFunction.groovy new file mode 100644 index 00000000000..54a1353808e --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/MatchingFunction.groovy @@ -0,0 +1,18 @@ +package org.prebid.server.functional.model.deals.lineitem.targeting + +import com.fasterxml.jackson.annotation.JsonValue + +enum MatchingFunction { + + MATCHES('$matches'), + IN('$in'), + INTERSECTS('$intersects'), + WITHIN('$within') + + @JsonValue + final String value + + private MatchingFunction(String value) { + this.value = value + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/MatchingFunctionNode.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/MatchingFunctionNode.groovy new file mode 100644 index 00000000000..6e639fe4383 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/MatchingFunctionNode.groovy @@ -0,0 +1,17 @@ +package org.prebid.server.functional.model.deals.lineitem.targeting + +import com.fasterxml.jackson.annotation.JsonValue +import groovy.transform.PackageScope + +@PackageScope +class MatchingFunctionNode { + + Map> matchingFunctionMultipleValuesNode + + Map matchingFunctionSingleValueNode + + @JsonValue + def getMatchingFunctionNode() { + matchingFunctionMultipleValuesNode ?: matchingFunctionSingleValueNode + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/Targeting.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/Targeting.groovy new file mode 100644 index 00000000000..12c9633cbaf --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/Targeting.groovy @@ -0,0 +1,92 @@ +package org.prebid.server.functional.model.deals.lineitem.targeting + +import com.fasterxml.jackson.annotation.JsonValue +import org.prebid.server.functional.model.deals.lineitem.LineItemSize + +import static BooleanOperator.AND +import static MatchingFunction.INTERSECTS +import static TargetingType.AD_UNIT_MEDIA_TYPE +import static TargetingType.AD_UNIT_SIZE +import static org.prebid.server.functional.model.deals.lineitem.MediaType.BANNER +import static org.prebid.server.functional.model.deals.lineitem.targeting.BooleanOperator.NOT +import static org.prebid.server.functional.model.deals.lineitem.targeting.BooleanOperator.OR + +class Targeting { + + private final Map> rootNode + + private final Map singleTargetingRootNode + + @JsonValue + def getSerializableRootNode() { + rootNode ?: singleTargetingRootNode + } + + private Targeting(Builder builder) { + rootNode = [(builder.rootOperator): builder.targetingNodes] + } + + private Targeting(Builder builder, TargetingNode targetingNode) { + singleTargetingRootNode = [(builder.rootOperator): targetingNode] + } + + Map> getTargetingRootNode() { + rootNode.asImmutable() + } + + static Targeting getDefaultTargeting() { + defaultTargetingBuilder.build() + } + + static Builder getDefaultTargetingBuilder() { + new Builder().addTargeting(AD_UNIT_SIZE, INTERSECTS, [LineItemSize.defaultLineItemSize]) + .addTargeting(AD_UNIT_MEDIA_TYPE, INTERSECTS, [BANNER]) + } + + static Targeting getInvalidTwoRootNodesTargeting() { + defaultTargeting.tap { rootNode.put(OR, []) } + } + + static class Builder { + + private BooleanOperator rootOperator + private List targetingNodes = [] + + Builder(BooleanOperator rootOperator = AND) { + this.rootOperator = rootOperator + } + + Builder addTargeting(TargetingType targetingType, + MatchingFunction matchingFunction, + List targetingValues) { + MatchingFunctionNode matchingFunctionNode = new MatchingFunctionNode(matchingFunctionMultipleValuesNode: [(matchingFunction): targetingValues]) + addTargetingNode(targetingType, matchingFunctionNode) + this + } + + Builder addTargeting(TargetingType targetingType, + MatchingFunction matchingFunction, + Object targetingValue) { + MatchingFunctionNode matchingFunctionNode = new MatchingFunctionNode(matchingFunctionSingleValueNode: [(matchingFunction): targetingValue]) + addTargetingNode(targetingType, matchingFunctionNode) + this + } + + private void addTargetingNode(TargetingType targetingType, + MatchingFunctionNode matchingFunctionNode) { + targetingNodes << new TargetingNode([(targetingType): matchingFunctionNode]) + } + + Targeting build() { + new Targeting(this) + } + + Targeting buildNotBooleanOperatorTargeting(TargetingType targetingType, + MatchingFunction matchingFunction, + List targetingValues) { + rootOperator = NOT + MatchingFunctionNode matchingFunctionNode = new MatchingFunctionNode(matchingFunctionSingleValueNode: [(matchingFunction): targetingValues]) + new Targeting(this, new TargetingNode([(targetingType): matchingFunctionNode])) + } + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/TargetingNode.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/TargetingNode.groovy new file mode 100644 index 00000000000..4e8ccecd318 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/TargetingNode.groovy @@ -0,0 +1,13 @@ +package org.prebid.server.functional.model.deals.lineitem.targeting + +import com.fasterxml.jackson.annotation.JsonValue +import groovy.transform.PackageScope +import groovy.transform.TupleConstructor + +@PackageScope +@TupleConstructor +class TargetingNode { + + @JsonValue + Map targetingNode +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/TargetingType.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/TargetingType.groovy new file mode 100644 index 00000000000..4813086c0ac --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/lineitem/targeting/TargetingType.groovy @@ -0,0 +1,36 @@ +package org.prebid.server.functional.model.deals.lineitem.targeting + +import com.fasterxml.jackson.annotation.JsonValue + +enum TargetingType { + + AD_UNIT_SIZE("adunit.size"), + AD_UNIT_MEDIA_TYPE("adunit.mediatype"), + AD_UNIT_AD_SLOT("adunit.adslot"), + SITE_DOMAIN("site.domain"), + REFERRER("site.referrer"), + APP_BUNDLE("app.bundle"), + DEVICE_COUNTRY("device.geo.ext.netacuity.country"), + DEVICE_TYPE("device.ext.deviceatlas.type"), + DEVICE_OS("device.ext.deviceatlas.osfamily"), + DEVICE_REGION("device.geo.ext.netacuity.region"), + PAGE_POSITION("pos"), + LOCATION("geo.distance"), + BIDDER_PARAM("bidp."), + USER_SEGMENT("segment."), + USER_SEGMENT_NAME(USER_SEGMENT.value + "name"), + UFPD("ufpd."), + UFPD_LANGUAGE(UFPD.value + "language"), + SFPD("sfpd."), + SFPD_AMP(SFPD.value + "amp"), + DOW("user.ext.time.userdow"), + HOUR("user.ext.time.userhour"), + INVALID("invalid.targeting.type") + + @JsonValue + final String value + + private TargetingType(String value) { + this.value = value + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/register/CurrencyServiceState.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/register/CurrencyServiceState.groovy new file mode 100644 index 00000000000..df2731249f4 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/register/CurrencyServiceState.groovy @@ -0,0 +1,11 @@ +package org.prebid.server.functional.model.deals.register + +import groovy.transform.ToString + +import java.time.ZonedDateTime + +@ToString(includeNames = true) +class CurrencyServiceState { + + ZonedDateTime lastUpdate +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/register/RegisterRequest.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/register/RegisterRequest.groovy new file mode 100644 index 00000000000..75daf33adc3 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/register/RegisterRequest.groovy @@ -0,0 +1,13 @@ +package org.prebid.server.functional.model.deals.register + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class RegisterRequest { + + BigDecimal healthIndex + Status status + String hostInstanceId + String region + String vendor +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/register/Status.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/register/Status.groovy new file mode 100644 index 00000000000..ad065e9ac4a --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/register/Status.groovy @@ -0,0 +1,11 @@ +package org.prebid.server.functional.model.deals.register + +import groovy.transform.ToString +import org.prebid.server.functional.model.deals.report.DeliveryStatisticsReport + +@ToString(includeNames = true, ignoreNulls = true) +class Status { + + CurrencyServiceState currencyRates + DeliveryStatisticsReport dealsStatus +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/report/DeliverySchedule.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/report/DeliverySchedule.groovy new file mode 100644 index 00000000000..5701757e569 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/report/DeliverySchedule.groovy @@ -0,0 +1,15 @@ +package org.prebid.server.functional.model.deals.report + +import groovy.transform.ToString + +import java.time.ZonedDateTime + +@ToString(includeNames = true, ignoreNulls = true) +class DeliverySchedule { + + String planId + ZonedDateTime planStartTimeStamp + ZonedDateTime planExpirationTimeStamp + ZonedDateTime planUpdatedTimeStamp + Set tokens +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/report/DeliveryStatisticsReport.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/report/DeliveryStatisticsReport.groovy new file mode 100644 index 00000000000..5ee7340c3dd --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/report/DeliveryStatisticsReport.groovy @@ -0,0 +1,19 @@ +package org.prebid.server.functional.model.deals.report + +import groovy.transform.ToString + +import java.time.ZonedDateTime + +@ToString(includeNames = true, ignoreNulls = true) +class DeliveryStatisticsReport { + + String reportId + String instanceId + String vendor + String region + Long clientAuctions + Set lineItemStatus + ZonedDateTime reportTimeStamp + ZonedDateTime dataWindowStartTimeStamp + ZonedDateTime dataWindowEndTimeStamp +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/report/Event.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/report/Event.groovy new file mode 100644 index 00000000000..495bfaf673e --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/report/Event.groovy @@ -0,0 +1,10 @@ +package org.prebid.server.functional.model.deals.report + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class Event { + + String type + Long count +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/report/LineItemStatus.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/report/LineItemStatus.groovy new file mode 100644 index 00000000000..a68029852c6 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/report/LineItemStatus.groovy @@ -0,0 +1,30 @@ +package org.prebid.server.functional.model.deals.report + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class LineItemStatus { + + String lineItemSource + String lineItemId + String dealId + String extLineItemId + Long accountAuctions + Long domainMatched + Long targetMatched + Long targetMatchedButFcapped + Long targetMatchedButFcapLookupFailed + Long pacingDeferred + Long sentToBidder + Long sentToBidderAsTopMatch + Long receivedFromBidder + Long receivedFromBidderInvalidated + Long sentToClient + Long sentToClientAsTopMatch + Set lostToLineItems + Set events + Set deliverySchedule + String readyAt + Long spentTokens + Long pacingFrequency +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/report/LostToLineItem.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/report/LostToLineItem.groovy new file mode 100644 index 00000000000..58567ffc974 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/report/LostToLineItem.groovy @@ -0,0 +1,11 @@ +package org.prebid.server.functional.model.deals.report + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class LostToLineItem { + + String lineItemSource + String lineItemId + Long count +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/report/Token.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/report/Token.groovy new file mode 100644 index 00000000000..89310a5d73e --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/report/Token.groovy @@ -0,0 +1,17 @@ +package org.prebid.server.functional.model.deals.report + +import com.fasterxml.jackson.annotation.JsonProperty +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class Token { + + @JsonProperty("class") + Integer priorityClass + + Integer total + + Long spent + + Long totalSpent +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/userdata/Segment.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/Segment.groovy new file mode 100644 index 00000000000..f11d8f32ff1 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/Segment.groovy @@ -0,0 +1,14 @@ +package org.prebid.server.functional.model.deals.userdata + +import groovy.transform.ToString +import org.prebid.server.functional.util.PBSUtils + +@ToString(includeNames = true, ignoreNulls = true) +class Segment { + + String id + + static getDefaultSegment() { + new Segment(id: PBSUtils.randomString) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/userdata/User.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/User.groovy new file mode 100644 index 00000000000..6d2e527a0e6 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/User.groovy @@ -0,0 +1,16 @@ +package org.prebid.server.functional.model.deals.userdata + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class User { + + List data + UserExt ext + + static getDefaultUser() { + new User(data: [UserData.defaultUserData], + ext: UserExt.defaultUserExt + ) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserData.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserData.groovy new file mode 100644 index 00000000000..5687d89285e --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserData.groovy @@ -0,0 +1,19 @@ +package org.prebid.server.functional.model.deals.userdata + +import groovy.transform.ToString +import org.prebid.server.functional.util.PBSUtils + +@ToString(includeNames = true, ignoreNulls = true) +class UserData { + + String id + String name + List segment + + static UserData getDefaultUserData() { + new UserData(id: PBSUtils.randomString, + name: PBSUtils.randomString, + segment: [Segment.defaultSegment] + ) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserDetails.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserDetails.groovy new file mode 100644 index 00000000000..780ec674b24 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserDetails.groovy @@ -0,0 +1,10 @@ +package org.prebid.server.functional.model.deals.userdata + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class UserDetails { + + List userData + List fcapIds +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserDetailsRequest.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserDetailsRequest.groovy new file mode 100644 index 00000000000..74985c5808f --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserDetailsRequest.groovy @@ -0,0 +1,12 @@ +package org.prebid.server.functional.model.deals.userdata + +import groovy.transform.ToString + +import java.time.ZonedDateTime + +@ToString(includeNames = true, ignoreNulls = true) +class UserDetailsRequest { + + ZonedDateTime time + List ids +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserDetailsResponse.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserDetailsResponse.groovy new file mode 100644 index 00000000000..864cfe7a290 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserDetailsResponse.groovy @@ -0,0 +1,14 @@ +package org.prebid.server.functional.model.deals.userdata + +import groovy.transform.ToString +import org.prebid.server.functional.model.ResponseModel + +@ToString(includeNames = true) +class UserDetailsResponse implements ResponseModel { + + User user + + static UserDetailsResponse getDefaultUserResponse(User user = User.defaultUser) { + new UserDetailsResponse(user: user) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserExt.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserExt.groovy new file mode 100644 index 00000000000..53a89aa97e2 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserExt.groovy @@ -0,0 +1,14 @@ +package org.prebid.server.functional.model.deals.userdata + +import groovy.transform.ToString +import org.prebid.server.functional.util.PBSUtils + +@ToString(includeNames = true, ignoreNulls = true) +class UserExt { + + List fcapIds + + static getDefaultUserExt() { + new UserExt(fcapIds: [PBSUtils.randomString]) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserId.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserId.groovy new file mode 100644 index 00000000000..8edeac5336d --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/UserId.groovy @@ -0,0 +1,10 @@ +package org.prebid.server.functional.model.deals.userdata + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class UserId { + + String type + String id +} diff --git a/src/test/groovy/org/prebid/server/functional/model/deals/userdata/WinEventNotification.groovy b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/WinEventNotification.groovy new file mode 100644 index 00000000000..bea8f7c296b --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/deals/userdata/WinEventNotification.groovy @@ -0,0 +1,19 @@ +package org.prebid.server.functional.model.deals.userdata + +import groovy.transform.ToString +import org.prebid.server.functional.model.deals.lineitem.FrequencyCap + +import java.time.ZonedDateTime + +@ToString(includeNames = true, ignoreNulls = true) +class WinEventNotification { + + String bidderCode + String bidId + String lineItemId + String region + List userIds + ZonedDateTime winEventDateTime + ZonedDateTime lineUpdatedDateTime + List frequencyCaps +} diff --git a/src/test/groovy/org/prebid/server/functional/model/mock/services/generalplanner/PlansResponse.groovy b/src/test/groovy/org/prebid/server/functional/model/mock/services/generalplanner/PlansResponse.groovy new file mode 100644 index 00000000000..f9a9d4548e7 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/mock/services/generalplanner/PlansResponse.groovy @@ -0,0 +1,19 @@ +package org.prebid.server.functional.model.mock.services.generalplanner + +import com.fasterxml.jackson.annotation.JsonValue +import org.prebid.server.functional.model.ResponseModel +import org.prebid.server.functional.model.deals.lineitem.LineItem + +class PlansResponse implements ResponseModel { + + List lineItems + + static PlansResponse getDefaultPlansResponse(String accountId) { + new PlansResponse(lineItems: [LineItem.getDefaultLineItem(accountId)]) + } + + @JsonValue + List getLineItems() { + lineItems + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/Deal.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/Deal.groovy index bb8b86ab594..487a26968da 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/Deal.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/Deal.groovy @@ -11,4 +11,5 @@ class Deal { Integer at List wseat List wadomain + DealExt ext } diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/DealExt.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/DealExt.groovy new file mode 100644 index 00000000000..cbb9913acb4 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/DealExt.groovy @@ -0,0 +1,9 @@ +package org.prebid.server.functional.model.request.auction + +import groovy.transform.ToString + +@ToString(includeNames = true) +class DealExt { + + DealLine line +} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/DealLine.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/DealLine.groovy new file mode 100644 index 00000000000..364d251f404 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/DealLine.groovy @@ -0,0 +1,15 @@ +package org.prebid.server.functional.model.request.auction + +import com.fasterxml.jackson.databind.PropertyNamingStrategies +import com.fasterxml.jackson.databind.annotation.JsonNaming +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) +class DealLine { + + String lineItemId + String extLineItemId + List sizes + String bidder +} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/PgMetrics.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/PgMetrics.groovy new file mode 100644 index 00000000000..50684b621c3 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/PgMetrics.groovy @@ -0,0 +1,23 @@ +package org.prebid.server.functional.model.request.auction + +import com.fasterxml.jackson.databind.PropertyNamingStrategies +import com.fasterxml.jackson.databind.annotation.JsonNaming +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy) +class PgMetrics { + + Set sentToClient + Set sentToClientAsTopMatch + Set matchedDomainTargeting + Set matchedWholeTargeting + Set matchedTargetingFcapped + Set matchedTargetingFcapLookupFailed + Set readyToServe + Set pacingDeferred + Map> sentToBidder + Map> sentToBidderAsTopMatch + Map> receivedFromBidder + Set responseInvalidated +} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/Pmp.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/Pmp.groovy index bd5f64fbe82..ce72554490b 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/Pmp.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/Pmp.groovy @@ -1,8 +1,11 @@ package org.prebid.server.functional.model.request.auction +import com.fasterxml.jackson.databind.PropertyNamingStrategies +import com.fasterxml.jackson.databind.annotation.JsonNaming import groovy.transform.ToString @ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy) class Pmp { Integer privateAuction diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy index 515e760b5cc..c660e971885 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy @@ -1,11 +1,11 @@ package org.prebid.server.functional.model.request.auction -import com.fasterxml.jackson.databind.PropertyNamingStrategy +import com.fasterxml.jackson.databind.PropertyNamingStrategies import com.fasterxml.jackson.databind.annotation.JsonNaming import groovy.transform.ToString import org.prebid.server.functional.model.bidder.BidderName -@JsonNaming(PropertyNamingStrategy.LowerCaseStrategy.class) +@JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) @ToString(includeNames = true, ignoreNulls = true) class Prebid { @@ -15,6 +15,7 @@ class Prebid { StoredRequest storedRequest Amp amp Channel channel + Map aliases List schains List multibid Pbs pbs diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/User.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/User.groovy index 8df6e8039d6..4f7a24c5bef 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/User.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/User.groovy @@ -1,6 +1,7 @@ package org.prebid.server.functional.model.request.auction import groovy.transform.ToString +import org.prebid.server.functional.util.PBSUtils @ToString(includeNames = true, ignoreNulls = true) class User { @@ -15,4 +16,8 @@ class User { Geo geo List data UserExt ext + + static getDefaultUser() { + new User(id: PBSUtils.randomString) + } } diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/UserExt.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/UserExt.groovy index 79b4b7b8c38..54b18b9835c 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/UserExt.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/UserExt.groovy @@ -6,4 +6,6 @@ import groovy.transform.ToString class UserExt { String consent + List fcapids + UserTime time } diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/UserTime.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/UserTime.groovy new file mode 100644 index 00000000000..bc81ab3fc6f --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/UserTime.groovy @@ -0,0 +1,10 @@ +package org.prebid.server.functional.model.request.auction + +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +class UserTime { + + Integer userdow + Integer userhour +} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/dealsupdate/ForceDealsUpdateRequest.groovy b/src/test/groovy/org/prebid/server/functional/model/request/dealsupdate/ForceDealsUpdateRequest.groovy new file mode 100644 index 00000000000..3cfdeec72ce --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/request/dealsupdate/ForceDealsUpdateRequest.groovy @@ -0,0 +1,48 @@ +package org.prebid.server.functional.model.request.dealsupdate + +import com.fasterxml.jackson.databind.PropertyNamingStrategies +import com.fasterxml.jackson.databind.annotation.JsonNaming +import groovy.transform.ToString + +import static org.prebid.server.functional.model.request.dealsupdate.ForceDealsUpdateRequest.Action.CREATE_REPORT +import static org.prebid.server.functional.model.request.dealsupdate.ForceDealsUpdateRequest.Action.INVALIDATE_LINE_ITEMS +import static org.prebid.server.functional.model.request.dealsupdate.ForceDealsUpdateRequest.Action.REGISTER_INSTANCE +import static org.prebid.server.functional.model.request.dealsupdate.ForceDealsUpdateRequest.Action.RESET_ALERT_COUNT +import static org.prebid.server.functional.model.request.dealsupdate.ForceDealsUpdateRequest.Action.SEND_REPORT +import static org.prebid.server.functional.model.request.dealsupdate.ForceDealsUpdateRequest.Action.UPDATE_LINE_ITEMS + +@ToString(includeNames = true) +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy) +class ForceDealsUpdateRequest { + + String actionName + + static ForceDealsUpdateRequest getUpdateLineItemsRequest() { + new ForceDealsUpdateRequest(actionName: UPDATE_LINE_ITEMS.name()) + } + + static ForceDealsUpdateRequest getSendReportRequest() { + new ForceDealsUpdateRequest(actionName: SEND_REPORT.name()) + } + + static ForceDealsUpdateRequest getRegisterInstanceRequest() { + new ForceDealsUpdateRequest(actionName: REGISTER_INSTANCE.name()) + } + + static ForceDealsUpdateRequest getResetAlertCountRequest() { + new ForceDealsUpdateRequest(actionName: RESET_ALERT_COUNT.name()) + } + + static ForceDealsUpdateRequest getCreateReportRequest() { + new ForceDealsUpdateRequest(actionName: CREATE_REPORT.name()) + } + + static ForceDealsUpdateRequest getInvalidateLineItemsRequest() { + new ForceDealsUpdateRequest(actionName: INVALIDATE_LINE_ITEMS.name()) + } + + private enum Action { + + UPDATE_LINE_ITEMS, SEND_REPORT, REGISTER_INSTANCE, RESET_ALERT_COUNT, CREATE_REPORT, INVALIDATE_LINE_ITEMS + } +} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/event/EventRequest.groovy b/src/test/groovy/org/prebid/server/functional/model/request/event/EventRequest.groovy index 6ed94f08161..9d7000cb7b3 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/event/EventRequest.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/event/EventRequest.groovy @@ -24,6 +24,8 @@ class EventRequest { Integer analytics @JsonProperty("ts") Long timestamp + @JsonProperty("l") + String lineItemId static EventRequest getDefaultEventRequest() { def request = new EventRequest() diff --git a/src/test/groovy/org/prebid/server/functional/model/response/Debug.groovy b/src/test/groovy/org/prebid/server/functional/model/response/Debug.groovy index 925b20a0322..5639ee694b9 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/Debug.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/Debug.groovy @@ -2,6 +2,7 @@ package org.prebid.server.functional.model.response import groovy.transform.ToString import org.prebid.server.functional.model.request.auction.BidRequest +import org.prebid.server.functional.model.request.auction.PgMetrics import org.prebid.server.functional.model.response.auction.HttpCall @ToString(includeNames = true, ignoreNulls = true) @@ -9,6 +10,7 @@ class Debug { Map> httpcalls BidRequest resolvedrequest + PgMetrics pgmetrics Map> getBidders() { def result = httpcalls?.findAll { it.key != "cache" } diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponse.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponse.groovy index 2398e99d576..16d50a6c085 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponse.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponse.groovy @@ -3,6 +3,7 @@ package org.prebid.server.functional.model.response.auction import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import org.prebid.server.functional.model.ResponseModel +import org.prebid.server.functional.model.mock.services.generalplanner.PlansResponse import org.prebid.server.functional.model.request.auction.BidRequest @EqualsAndHashCode @@ -29,6 +30,16 @@ class BidResponse implements ResponseModel { bidResponse } + static BidResponse getDefaultPgBidResponse(BidRequest bidRequest, PlansResponse plansResponse) { + def bidResponse = getDefaultBidResponse(bidRequest) + def bid = bidResponse.seatbid[0].bid[0] + def lineItem = plansResponse.lineItems[0] + bid.dealid = lineItem.dealId + bid.w = lineItem.sizes[0].w + bid.h = lineItem.sizes[0].h + bidResponse + } + static private List getDefaultBids(List impIds) { impIds.collect { Bid.getDefaultBid(it) } } diff --git a/src/test/groovy/org/prebid/server/functional/pg/BasePgSpec.groovy b/src/test/groovy/org/prebid/server/functional/pg/BasePgSpec.groovy new file mode 100644 index 00000000000..d81f54b1625 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/pg/BasePgSpec.groovy @@ -0,0 +1,49 @@ +package org.prebid.server.functional.pg + +import org.prebid.server.functional.model.deals.userdata.UserDetailsResponse +import org.prebid.server.functional.service.PrebidServerService +import org.prebid.server.functional.testcontainers.PBSTest +import org.prebid.server.functional.testcontainers.PbsContainerProperties +import org.prebid.server.functional.testcontainers.PbsPgConfig +import org.prebid.server.functional.testcontainers.PbsServiceFactory +import org.prebid.server.functional.testcontainers.scaffolding.Bidder +import org.prebid.server.functional.testcontainers.scaffolding.pg.Alert +import org.prebid.server.functional.testcontainers.scaffolding.pg.DeliveryStatistics +import org.prebid.server.functional.testcontainers.scaffolding.pg.GeneralPlanner +import org.prebid.server.functional.testcontainers.scaffolding.pg.UserData +import org.prebid.server.functional.util.ObjectMapperWrapper +import spock.lang.Specification + +import static org.prebid.server.functional.testcontainers.Dependencies.networkServiceContainer +import static org.prebid.server.functional.testcontainers.Dependencies.objectMapperWrapper + +@PBSTest +abstract class BasePgSpec extends Specification { + + protected static final ObjectMapperWrapper mapper = objectMapperWrapper + protected static final PbsServiceFactory pbsServiceFactory = new PbsServiceFactory(networkServiceContainer, mapper) + + protected static final GeneralPlanner generalPlanner = new GeneralPlanner(networkServiceContainer, mapper).tap { + setResponse() + } + protected static final DeliveryStatistics deliveryStatistics = new DeliveryStatistics(networkServiceContainer, mapper) + protected static final Alert alert = new Alert(networkServiceContainer, mapper) + protected static final UserData userData = new UserData(networkServiceContainer, mapper) + + private static final Map pgPbsConfig = pbsServiceFactory.generalSettings() + + PbsPgConfig.getPgConfig(networkServiceContainer) + protected static final PrebidServerService pgPbsService = pbsServiceFactory.getService(pgPbsConfig) + protected static final PbsContainerProperties pgPbsProperties = new PbsContainerProperties(pbsServiceFactory.getContainer(pgPbsConfig)) + protected static final Bidder bidder = new Bidder(networkServiceContainer, mapper) + + def setupSpec() { + generalPlanner.setResponse() + + deliveryStatistics.setResponse() + + alert.setResponse() + + userData.setResponse() + userData.setUserDataResponse(UserDetailsResponse.defaultUserResponse) + } +} 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 32e2db11e72..26d2ee9288e 100644 --- a/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy +++ b/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy @@ -11,6 +11,7 @@ import org.prebid.server.functional.model.mock.services.prebidcache.response.Pre import org.prebid.server.functional.model.request.amp.AmpRequest import org.prebid.server.functional.model.request.auction.BidRequest import org.prebid.server.functional.model.request.cookiesync.CookieSyncRequest +import org.prebid.server.functional.model.request.dealsupdate.ForceDealsUpdateRequest import org.prebid.server.functional.model.request.event.EventRequest import org.prebid.server.functional.model.request.logging.httpinteraction.HttpInteractionRequest import org.prebid.server.functional.model.request.setuid.SetuidRequest @@ -55,6 +56,7 @@ class PrebidServerService { static final String CURRENCY_RATES_ENDPOINT = "/currency/rates" static final String HTTP_INTERACTION_ENDPOINT = "/logging/httpinteraction" static final String COLLECTED_METRICS_ENDPOINT = "/collected-metrics" + static final String FORCE_DEALS_UPDATE_ENDPOINT = "/pbs-admin/force-deals-update" private final PrebidServerContainer pbsContainer private final ObjectMapperWrapper mapper @@ -165,8 +167,9 @@ class PrebidServerService { } @Step("[GET] /event") - byte[] sendEventRequest(EventRequest eventRequest) { - def response = given(requestSpecification).queryParams(mapper.toMap(eventRequest)) + byte[] sendEventRequest(EventRequest eventRequest, Map headers = [:]) { + def response = given(requestSpecification).headers(headers) + .queryParams(mapper.toMap(eventRequest)) .get(EVENT_ENDPOINT) checkResponseStatusCode(response) @@ -250,6 +253,14 @@ class PrebidServerService { mapper.decode(response.asString(), new TypeReference>() {}) } + @Step("[GET] /pbs-admin/force-deals-update") + void sendForceDealsUpdateRequest(ForceDealsUpdateRequest forceDealsUpdateRequest) { + def response = given(adminRequestSpecification).queryParams(mapper.toMap(forceDealsUpdateRequest)) + .get(FORCE_DEALS_UPDATE_ENDPOINT) + + checkResponseStatusCode(response, 204) + } + private Response postAuction(BidRequest bidRequest, Map headers = [:]) { def payload = mapper.encode(bidRequest) @@ -264,12 +275,12 @@ class PrebidServerService { .get(AMP_ENDPOINT) } - private void checkResponseStatusCode(Response response) { - def statusCode = response.statusCode - if (statusCode != 200) { + private void checkResponseStatusCode(Response response, int statusCode = 200) { + def responseStatusCode = response.statusCode + if (responseStatusCode != statusCode) { def responseBody = response.body.asString() log.error(responseBody) - throw new PrebidServerException(statusCode, responseBody, getHeaders(response)) + throw new PrebidServerException(responseStatusCode, responseBody, getHeaders(response)) } } diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/PbsContainerProperties.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/PbsContainerProperties.groovy new file mode 100644 index 00000000000..7539e9b1a91 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/PbsContainerProperties.groovy @@ -0,0 +1,45 @@ +package org.prebid.server.functional.testcontainers + +import org.prebid.server.functional.testcontainers.container.PrebidServerContainer + +import static org.prebid.server.functional.testcontainers.container.PrebidServerContainer.normalizeProperty + +class PbsContainerProperties { + + String env + String dataCenter + String region + String system + String subSystem + String hostId + String vendor + String currency + String userIdType + int maxDealsPerBidder + int lineItemsPerReport + + PbsContainerProperties(PrebidServerContainer prebidServerContainer) { + Map properties = prebidServerContainer.envMap + + env = getStringProperty(properties, "profile") + dataCenter = getStringProperty(properties, "data-center") + region = getStringProperty(properties, "datacenter-region") + system = getStringProperty(properties, "system") + subSystem = getStringProperty(properties, "sub-system") + hostId = getStringProperty(properties, "host-id") + vendor = getStringProperty(properties, "vendor") + currency = getStringProperty(properties, "auction.ad-server-currency") + userIdType = getStringProperty(properties, "deals.user-data.user-ids[0].type") + maxDealsPerBidder = getIntProperty(properties, "deals.max-deals-per-bidder") + lineItemsPerReport = getIntProperty(properties, "deals.delivery-stats.line-items-per-report") + } + + private static getStringProperty(Map properties, String propertyName) { + properties.get(normalizeProperty(propertyName)) + } + + private static getIntProperty(Map properties, String propertyName) { + def property = properties.get(normalizeProperty(propertyName)) + property ? property as int : -1 + } +} diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/PbsPgConfig.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/PbsPgConfig.groovy new file mode 100644 index 00000000000..1795b2e71c3 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/PbsPgConfig.groovy @@ -0,0 +1,86 @@ +package org.prebid.server.functional.testcontainers + +import org.prebid.server.functional.testcontainers.container.NetworkServiceContainer + +import java.time.LocalDate + +import static org.prebid.server.functional.testcontainers.scaffolding.pg.Alert.ALERT_ENDPOINT_PATH +import static org.prebid.server.functional.testcontainers.scaffolding.pg.DeliveryStatistics.REPORT_DELIVERY_ENDPOINT_PATH +import static org.prebid.server.functional.testcontainers.scaffolding.pg.GeneralPlanner.PLANS_ENDPOINT_PATH +import static org.prebid.server.functional.testcontainers.scaffolding.pg.GeneralPlanner.REGISTER_ENDPOINT_PATH +import static org.prebid.server.functional.testcontainers.scaffolding.pg.UserData.USER_DETAILS_ENDPOINT_PATH +import static org.prebid.server.functional.testcontainers.scaffolding.pg.UserData.WIN_EVENT_ENDPOINT_PATH + +class PbsPgConfig { + + public static final String PG_ENDPOINT_USERNAME = "pg" + public static final String PG_ENDPOINT_PASSWORD = "pg" + + private static final Integer NEXT_MONTH = LocalDate.now().plusMonths(1).monthValue + + static Map getPgConfig(NetworkServiceContainer networkServiceContainer) { + adminDealsUpdateEndpoint() + deals() + planner(networkServiceContainer) + + deliveryStatistics(networkServiceContainer) + deliveryProgress() + alert(networkServiceContainer) + + userData(networkServiceContainer) + } + + static Map adminDealsUpdateEndpoint() { + ["admin-endpoints.force-deals-update.enabled": "true"] + } + + static Map deals() { + ["deals.enabled" : "true", + "deals.simulation.enabled" : "false", + "deals.max-deals-per-bidder": "3" + ] + } + + static Map planner(NetworkServiceContainer networkServiceContainer) { + String rootUri = networkServiceContainer.rootUri + ["deals.planner.plan-endpoint" : rootUri + PLANS_ENDPOINT_PATH, + "deals.planner.register-endpoint" : rootUri + REGISTER_ENDPOINT_PATH, + "deals.planner.update-period" : "0 15 10 15 $NEXT_MONTH ?" as String, + "deals.planner.plan-advance-period": "0 15 10 15 $NEXT_MONTH ?" as String, + "deals.planner.timeout-ms" : "5000", + "deals.planner.username" : PG_ENDPOINT_USERNAME, + "deals.planner.password" : PG_ENDPOINT_PASSWORD, + "deals.planner.register-period-sec": "3600" + ] + } + + static Map deliveryStatistics(NetworkServiceContainer networkServiceContainer) { + ["deals.delivery-stats.endpoint" : networkServiceContainer.rootUri + + REPORT_DELIVERY_ENDPOINT_PATH, + "deals.delivery-stats.username" : PG_ENDPOINT_USERNAME, + "deals.delivery-stats.password" : PG_ENDPOINT_PASSWORD, + "deals.delivery-stats.delivery-period" : "0 15 10 15 $NEXT_MONTH ?" as String, + "deals.delivery-stats.timeout-ms" : "10000", + "deals.delivery-stats.request-compression-enabled": "false", + "deals.delivery-stats.line-items-per-report" : "5" + ] + } + + static Map deliveryProgress() { + ["deals.delivery-progress.report-reset-period": "0 15 10 15 $NEXT_MONTH ?" as String] + } + + static Map alert(NetworkServiceContainer networkServiceContainer) { + ["deals.alert-proxy.enabled" : "true", + "deals.alert-proxy.url" : networkServiceContainer.rootUri + ALERT_ENDPOINT_PATH, + "deals.alert-proxy.username" : PG_ENDPOINT_USERNAME, + "deals.alert-proxy.password" : PG_ENDPOINT_PASSWORD, + "deals.alert-proxy.timeout-sec": "10" + ] + } + + static Map userData(NetworkServiceContainer networkServiceContainer) { + String rootUri = networkServiceContainer.rootUri + ["deals.user-data.user-details-endpoint": rootUri + USER_DETAILS_ENDPOINT_PATH, + "deals.user-data.win-event-endpoint" : rootUri + WIN_EVENT_ENDPOINT_PATH, + "deals.user-data.timeout" : "1000", + "deals.user-data.user-ids[0].type" : "autotest", + "deals.user-data.user-ids[0].source" : "uid", + "deals.user-data.user-ids[0].location" : "generic" + ] + } +} diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/PbsServiceFactory.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/PbsServiceFactory.groovy index ad40d76bf86..aaa70e6081f 100644 --- a/src/test/groovy/org/prebid/server/functional/testcontainers/PbsServiceFactory.groovy +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/PbsServiceFactory.groovy @@ -4,6 +4,7 @@ import org.prebid.server.functional.service.PrebidServerService import org.prebid.server.functional.testcontainers.container.NetworkServiceContainer import org.prebid.server.functional.testcontainers.container.PrebidServerContainer import org.prebid.server.functional.util.ObjectMapperWrapper +import org.prebid.server.functional.util.PBSUtils class PbsServiceFactory { @@ -24,7 +25,7 @@ class PbsServiceFactory { remove([(container.key): container.value]) } if (containers.containsKey(config)) { - return new PrebidServerService(containers.get(config), mapper) + return new PrebidServerService(getContainer(config), mapper) } else { def pbsContainer = new PrebidServerContainer(config) pbsContainer.start() @@ -33,6 +34,10 @@ class PbsServiceFactory { } } + static PrebidServerContainer getContainer(Map config) { + containers.get(config) + } + static void stopContainers() { def containers = containers.findAll { it.key != [:] } remove(containers) @@ -54,6 +59,17 @@ class PbsServiceFactory { "settings.http.category-endpoint": "$networkServiceContainer.rootUri/video-categories".toString()] } + static Map generalSettings() { + ["host-id" : PBSUtils.randomString, + "datacenter-region": PBSUtils.randomString, + "vendor" : PBSUtils.randomString, + "profile" : PBSUtils.randomString, + "system" : PBSUtils.randomString, + "sub-system" : PBSUtils.randomString, + "data-center" : PBSUtils.randomString + ] + } + private static void remove(Map, PrebidServerContainer> map) { map.each { key, value -> value.stop() diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/container/PrebidServerContainer.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/container/PrebidServerContainer.groovy index ee13e094c6d..58d00d3e992 100644 --- a/src/test/groovy/org/prebid/server/functional/testcontainers/container/PrebidServerContainer.groovy +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/container/PrebidServerContainer.groovy @@ -10,8 +10,8 @@ class PrebidServerContainer extends GenericContainer { public static final int PORT = 8080 public static final int DEBUG_PORT = 8000 public static final int ADMIN_PORT = 8060 - public static final String ADMIN_ENDPOINT_USERNAME = "user" - public static final String ADMIN_ENDPOINT_PASSWORD = "user" + public static final String ADMIN_ENDPOINT_USERNAME = "admin" + public static final String ADMIN_ENDPOINT_PASSWORD = "admin" private static final String DB_ACCOUNT_QUERY = """ SELECT JSON_MERGE_PATCH(JSON_OBJECT('id', uuid, @@ -75,7 +75,7 @@ LIMIT 1 } PrebidServerContainer withDebug() { - withEnv("JAVA_TOOL_OPTIONS", "-agentlib:jdwp=transport=dt_socket,address=$DEBUG_PORT,server=y,suspend=n") + withEnv("JAVA_TOOL_OPTIONS", "-agentlib:jdwp=transport=dt_socket,address=*:$DEBUG_PORT,server=y,suspend=n") } void withMysql(String host, int port, String dbname, String user, String password) { @@ -151,13 +151,15 @@ LIMIT 1 return "http://$host:$adminPort" } - private static Map normalizeProperties(Map properties) { - properties.collectEntries { [normalizeProperty(it.key), it.value] } as Map - } - - private static String normalizeProperty(String property) { + static String normalizeProperty(String property) { property.replace(".", "_") .replace("-", "") + .replace("[", "_") + .replace("]", "_") + } + + private static Map normalizeProperties(Map properties) { + properties.collectEntries { [normalizeProperty(it.key), it.value] } as Map } @Override diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/NetworkScaffolding.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/NetworkScaffolding.groovy index 01d40a98ce8..949078179b3 100644 --- a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/NetworkScaffolding.groovy +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/NetworkScaffolding.groovy @@ -2,12 +2,15 @@ package org.prebid.server.functional.testcontainers.scaffolding import org.mockserver.client.MockServerClient import org.mockserver.matchers.Times +import org.mockserver.model.ClearType import org.mockserver.model.HttpRequest +import org.mockserver.model.HttpStatusCode import org.prebid.server.functional.model.ResponseModel import org.prebid.server.functional.util.ObjectMapperWrapper import org.testcontainers.containers.MockServerContainer import static java.util.concurrent.TimeUnit.SECONDS +import static org.mockserver.model.ClearType.EXPECTATIONS import static org.mockserver.model.HttpRequest.request import static org.mockserver.model.HttpResponse.response import static org.mockserver.model.HttpStatusCode.OK_200 @@ -67,10 +70,13 @@ abstract class NetworkScaffolding { expectedCountReached } - void setResponse(HttpRequest httpRequest, ResponseModel responseModel) { + void setResponse(HttpRequest httpRequest, + ResponseModel responseModel, + HttpStatusCode statusCode = OK_200, + Times times = Times.exactly(1)) { def mockResponse = mapper.encode(responseModel) - mockServerClient.when(httpRequest, Times.exactly(1)) - .respond(response().withStatusCode(OK_200.code()) + mockServerClient.when(httpRequest, times) + .respond(response().withStatusCode(statusCode.code()) .withBody(mockResponse, APPLICATION_JSON)) } @@ -135,8 +141,8 @@ abstract class NetworkScaffolding { getRequestsHeaders(mockServerClient.retrieveRecordedRequests(getRequest(value)) as List) } - void reset() { - mockServerClient.clear(request().withPath(endpoint)) + void reset(String resetEndpoint = endpoint, ClearType clearType = EXPECTATIONS) { + mockServerClient.clear(request().withPath(resetEndpoint), clearType) } private static List> getRequestsHeaders(List httpRequests) { diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/Alert.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/Alert.groovy new file mode 100644 index 00000000000..eee97fb728f --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/Alert.groovy @@ -0,0 +1,50 @@ +package org.prebid.server.functional.testcontainers.scaffolding.pg + +import com.fasterxml.jackson.core.type.TypeReference +import org.mockserver.model.HttpRequest +import org.prebid.server.functional.model.deals.alert.AlertEvent +import org.prebid.server.functional.testcontainers.scaffolding.NetworkScaffolding +import org.prebid.server.functional.util.ObjectMapperWrapper +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.mockserver.model.JsonPathBody.jsonPath + +class Alert extends NetworkScaffolding { + + static final String ALERT_ENDPOINT_PATH = "/deals/alert" + + Alert(MockServerContainer mockServerContainer, ObjectMapperWrapper mapper) { + super(mockServerContainer, ALERT_ENDPOINT_PATH, mapper) + } + + AlertEvent getRecordedAlertRequest() { + def body = getRecordedRequestsBody(request).last() + // 0 index element is returned after deserialization as PBS responses with SingletonList + mapper.decode(body, new TypeReference>() {})[0] + } + + Map getLastRecordedAlertRequestHeaders() { + getLastRecordedRequestHeaders(request) + } + + void setResponse() { + mockServerClient.when(request().withPath(endpoint)) + .respond(response().withStatusCode(OK_200.code())) + } + + @Override + protected HttpRequest getRequest(String alertId) { + request().withMethod("POST") + .withPath(ALERT_ENDPOINT_PATH) + .withBody(jsonPath("\$[?(@.id == '$alertId')]")) + } + + @Override + protected HttpRequest getRequest() { + request().withMethod("POST") + .withPath(ALERT_ENDPOINT_PATH) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/DeliveryStatistics.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/DeliveryStatistics.groovy new file mode 100644 index 00000000000..b0b8d80b836 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/DeliveryStatistics.groovy @@ -0,0 +1,58 @@ +package org.prebid.server.functional.testcontainers.scaffolding.pg + +import org.mockserver.model.HttpRequest +import org.mockserver.model.HttpStatusCode +import org.prebid.server.functional.model.deals.report.DeliveryStatisticsReport +import org.prebid.server.functional.testcontainers.scaffolding.NetworkScaffolding +import org.prebid.server.functional.util.ObjectMapperWrapper +import org.testcontainers.containers.MockServerContainer + +import static org.mockserver.model.ClearType.ALL +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.mockserver.model.JsonPathBody.jsonPath + +class DeliveryStatistics extends NetworkScaffolding { + + static final String REPORT_DELIVERY_ENDPOINT_PATH = "/deals/report/delivery" + + DeliveryStatistics(MockServerContainer mockServerContainer, ObjectMapperWrapper mapper) { + super(mockServerContainer, REPORT_DELIVERY_ENDPOINT_PATH, mapper) + } + + Map getLastRecordedDeliveryRequestHeaders() { + getLastRecordedRequestHeaders(request) + } + + DeliveryStatisticsReport getLastRecordedDeliveryStatisticsReportRequest() { + recordedDeliveryStatisticsReportRequests.last() + } + + void resetRecordedRequests() { + reset(REPORT_DELIVERY_ENDPOINT_PATH, ALL) + } + + void setResponse(HttpStatusCode statusCode = OK_200) { + mockServerClient.when(request().withPath(endpoint)) + .respond(response().withStatusCode(statusCode.code())) + } + + List getRecordedDeliveryStatisticsReportRequests() { + def body = getRecordedRequestsBody(request) + body.collect { mapper.decode(it, DeliveryStatisticsReport) } + } + + @Override + protected HttpRequest getRequest(String reportId) { + request().withMethod("POST") + .withPath(REPORT_DELIVERY_ENDPOINT_PATH) + .withBody(jsonPath("\$[?(@.reportId == '$reportId')]")) + } + + @Override + protected HttpRequest getRequest() { + request().withMethod("POST") + .withPath(REPORT_DELIVERY_ENDPOINT_PATH) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/GeneralPlanner.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/GeneralPlanner.groovy new file mode 100644 index 00000000000..0ce77f5a722 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/GeneralPlanner.groovy @@ -0,0 +1,87 @@ +package org.prebid.server.functional.testcontainers.scaffolding.pg + +import org.mockserver.matchers.Times +import org.mockserver.model.HttpRequest +import org.mockserver.model.HttpStatusCode +import org.prebid.server.functional.model.deals.register.RegisterRequest +import org.prebid.server.functional.model.mock.services.generalplanner.PlansResponse +import org.prebid.server.functional.testcontainers.scaffolding.NetworkScaffolding +import org.prebid.server.functional.util.ObjectMapperWrapper +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.mockserver.model.JsonPathBody.jsonPath + +class GeneralPlanner extends NetworkScaffolding { + + static final String PLANS_ENDPOINT_PATH = "/deals/plans" + static final String REGISTER_ENDPOINT_PATH = "/deals/register" + + GeneralPlanner(MockServerContainer mockServerContainer, ObjectMapperWrapper mapper) { + super(mockServerContainer, REGISTER_ENDPOINT_PATH, mapper) + } + + void initRegisterResponse(HttpStatusCode statusCode = OK_200) { + reset() + setResponse(statusCode) + } + + void initPlansResponse(PlansResponse plansResponse, HttpStatusCode statusCode = OK_200, Times times = Times.exactly(1)) { + resetPlansEndpoint() + setPlansResponse(plansResponse, statusCode, times) + } + + void resetPlansEndpoint() { + reset(PLANS_ENDPOINT_PATH) + } + + int getRecordedPlansRequestCount() { + getRequestCount(plansRequest) + } + + RegisterRequest getLastRecordedRegisterRequest() { + recordedRegisterRequests.last() + } + + List getRecordedRegisterRequests() { + def body = getRecordedRequestsBody(request) + body.collect { mapper.decode(it, RegisterRequest) } + } + + void setResponse(HttpStatusCode statusCode = OK_200) { + mockServerClient.when(request().withPath(endpoint)) + .respond(response().withStatusCode(statusCode.code())) + } + + Map getLastRecordedRegisterRequestHeaders() { + getLastRecordedRequestHeaders(request) + } + + Map getLastRecordedPlansRequestHeaders() { + getLastRecordedRequestHeaders(plansRequest) + } + + private void setPlansResponse(PlansResponse plansResponse, HttpStatusCode statusCode, Times times = Times.exactly(1)) { + setResponse(plansRequest, plansResponse, statusCode, times) + } + + @Override + protected HttpRequest getRequest(String hostInstanceId) { + request().withMethod("POST") + .withPath(REGISTER_ENDPOINT_PATH) + .withBody(jsonPath("\$[?(@.hostInstanceId == '$hostInstanceId')]")) + } + + @Override + protected HttpRequest getRequest() { + request().withMethod("POST") + .withPath(REGISTER_ENDPOINT_PATH) + } + + private static HttpRequest getPlansRequest() { + request().withMethod("GET") + .withPath(PLANS_ENDPOINT_PATH) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/UserData.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/UserData.groovy new file mode 100644 index 00000000000..c67a8cbf337 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/pg/UserData.groovy @@ -0,0 +1,71 @@ +package org.prebid.server.functional.testcontainers.scaffolding.pg + +import org.mockserver.model.HttpRequest +import org.mockserver.model.HttpStatusCode +import org.prebid.server.functional.model.deals.userdata.UserDetailsRequest +import org.prebid.server.functional.model.deals.userdata.UserDetailsResponse +import org.prebid.server.functional.model.deals.userdata.WinEventNotification +import org.prebid.server.functional.testcontainers.scaffolding.NetworkScaffolding +import org.prebid.server.functional.util.ObjectMapperWrapper +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.mockserver.model.JsonPathBody.jsonPath + +class UserData extends NetworkScaffolding { + + static final String USER_DETAILS_ENDPOINT_PATH = "/deals/user-details" + static final String WIN_EVENT_ENDPOINT_PATH = "/deals/win-event" + + UserData(MockServerContainer mockServerContainer, ObjectMapperWrapper mapper) { + super(mockServerContainer, WIN_EVENT_ENDPOINT_PATH, mapper) + } + + UserDetailsRequest getRecordedUserDetailsRequest() { + def body = getRecordedRequestsBody(userDetailsRequest).last() + mapper.decode(body, UserDetailsRequest) + } + + WinEventNotification getRecordedWinEventRequest() { + def body = getRecordedRequestsBody(request).last() + mapper.decode(body, WinEventNotification) + } + + void setUserDataResponse(UserDetailsResponse userDataResponse, HttpStatusCode httpStatusCode = OK_200) { + resetUserDetailsEndpoint() + setResponse(userDetailsRequest, userDataResponse, httpStatusCode) + } + + int getRecordedUserDetailsRequestCount() { + getRequestCount(userDetailsRequest) + } + + void resetUserDetailsEndpoint() { + reset(USER_DETAILS_ENDPOINT_PATH) + } + + void setResponse() { + mockServerClient.when(request().withPath(endpoint)) + .respond(response().withStatusCode(OK_200.code())) + } + + @Override + protected HttpRequest getRequest(String bidId) { + request().withMethod("POST") + .withPath(WIN_EVENT_ENDPOINT_PATH) + .withBody(jsonPath("\$[?(@.bidId == '$bidId')]")) + } + + @Override + protected HttpRequest getRequest() { + request().withMethod("POST") + .withPath(WIN_EVENT_ENDPOINT_PATH) + } + + private static HttpRequest getUserDetailsRequest() { + request().withMethod("POST") + .withPath(USER_DETAILS_ENDPOINT_PATH) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/util/HttpUtil.groovy b/src/test/groovy/org/prebid/server/functional/util/HttpUtil.groovy new file mode 100644 index 00000000000..937c9716361 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/util/HttpUtil.groovy @@ -0,0 +1,33 @@ +package org.prebid.server.functional.util + +import org.prebid.server.functional.model.request.setuid.UidsCookie + +class HttpUtil { + + public static final String UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/ + + public static final String PG_TRX_ID_HEADER = "pg-trx-id" + public static final String AUTHORIZATION_HEADER = "Authorization" + public static final String ACCEPT_HEADER = "Authorization" + public static final String CONTENT_TYPE_HEADER = "Content-Type" + public static final String COOKIE_HEADER = "cookie" + + public static final String CONTENT_TYPE_HEADER_VALUE = "application/json" + public static final String CHARSET_HEADER_VALUE = "charset=utf-8" + + static String makeBasicAuthHeaderValue(String username, String password) { + "Basic ${encode("$username:$password")}" + } + + static HashMap getCookieHeader(ObjectMapperWrapper mapper, UidsCookie uidsCookie) { + [(COOKIE_HEADER): makeUidsCookieHeaderValue(mapper.encode(uidsCookie))] + } + + private static String makeUidsCookieHeaderValue(String uidsCookieJson) { + "uids=${encode(uidsCookieJson)}" + } + + private static encode(String string) { + Base64.encoder.encodeToString(string.bytes) + } +} diff --git a/src/test/groovy/org/prebid/server/functional/util/PBSUtils.groovy b/src/test/groovy/org/prebid/server/functional/util/PBSUtils.groovy index 4020a66e203..8f89d8ff886 100644 --- a/src/test/groovy/org/prebid/server/functional/util/PBSUtils.groovy +++ b/src/test/groovy/org/prebid/server/functional/util/PBSUtils.groovy @@ -7,6 +7,8 @@ import java.util.stream.IntStream import static java.lang.Integer.MAX_VALUE import static java.lang.Integer.MIN_VALUE +import static java.util.concurrent.TimeUnit.MILLISECONDS +import static org.awaitility.Awaitility.with class PBSUtils { @@ -32,4 +34,12 @@ class PBSUtils { static String getRandomString(int stringLength = 20) { RandomStringUtils.randomAlphanumeric(stringLength) } + + static void waitUntil(Closure closure, long timeout = 1000, long pollInterval = 100) { + with().pollDelay(0, MILLISECONDS) + .pollInterval(pollInterval, MILLISECONDS) + .await() + .atMost(timeout, MILLISECONDS) + .until(closure) + } }