Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Response correction: Fix VAST matching #3493

Merged
merged 8 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Pattern;

Expand All @@ -29,7 +30,7 @@ public class AppVideoHtmlCorrection implements Correction {
private static final ConditionalLogger conditionalLogger = new ConditionalLogger(
LoggerFactory.getLogger(AppVideoHtmlCorrection.class));

private static final Pattern VAST_XML_PATTERN = Pattern.compile("<\\w*VAST\\w+", Pattern.CASE_INSENSITIVE);
private static final Pattern VAST_XML_PATTERN = Pattern.compile(".*<\\s*VAST\\s+.*", Pattern.CASE_INSENSITIVE);
private static final TypeReference<ExtPrebid<ExtBidPrebid, ObjectNode>> EXT_BID_PREBID_TYPE_REFERENCE =
new TypeReference<>() {
};
Expand All @@ -42,7 +43,7 @@ public class AppVideoHtmlCorrection implements Correction {
private final double logSamplingRate;

public AppVideoHtmlCorrection(ObjectMapper mapper, double logSamplingRate) {
this.mapper = mapper;
this.mapper = Objects.requireNonNull(mapper);
this.logSamplingRate = logSamplingRate;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public void applyShouldNotChangeBidResponsesWhenBidIsVideoAndHasVastXmlInAdm() {
final List<BidderResponse> givenResponses = List.of(
BidderResponse.of("bidderA", null, 100),
BidderResponse.of("bidderB", BidderSeatBid.of(
List.of(givenBid("<anythingvAstanything", BidType.video))), 100));
List.of(givenBid("< \tVAST anything>", BidType.video))), 100));

// when
final List<BidderResponse> actual = target.apply(givenConfig, givenResponses);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class ResponseCorrectionSpec extends ModuleBaseSpec {
"adapters.generic.modifying-vast-xml-allowed": "false"] +
responseCorrectionConfig)

private final static int OPTIMAL_MAX_LENGTH = 20

def "PBS shouldn't modify response when in account correction module disabled"() {
given: "Start up time"
def start = Instant.now()
Expand Down Expand Up @@ -326,7 +328,7 @@ class ResponseCorrectionSpec extends ModuleBaseSpec {

and: "Set bidder response"
def bidResponse = BidResponse.getDefaultBidResponse(bidRequest).tap {
seatbid[0].bid[0].setAdm(PBSUtils.getRandomCase("<${PBSUtils.randomString}VAST${PBSUtils.randomString}"))
seatbid[0].bid[0].setAdm(PBSUtils.getRandomCase(admValue))
}
bidder.setResponse(bidRequest.id, bidResponse)

Expand All @@ -352,6 +354,69 @@ class ResponseCorrectionSpec extends ModuleBaseSpec {

and: "Response shouldn't contain warnings"
assert !response.ext.warnings

where:
admValue << [
"${PBSUtils.randomString}<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST ${PBSUtils.randomString}",
"${PBSUtils.randomString}<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST ${PBSUtils.randomString}>",
"${PBSUtils.randomString}${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST ${PBSUtils.randomString}>",
"<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST${' ' * PBSUtils.getRandomNumber(1, OPTIMAL_MAX_LENGTH)}",
"<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST${' ' * PBSUtils.getRandomNumber(1, OPTIMAL_MAX_LENGTH)}>",
"<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST${' ' * PBSUtils.getRandomNumber(1, OPTIMAL_MAX_LENGTH)}${PBSUtils.randomString}>"
]
}

def "PBS should modify response when requested video impression respond with invalid adm VAST keyword"() {
given: "Start up time"
def start = Instant.now()

and: "Default bid request with APP and Video imp"
def bidRequest = getDefaultVideoRequest(APP)

and: "Set bidder response"
def bidResponse = BidResponse.getDefaultBidResponse(bidRequest).tap {
seatbid[0].bid[0].setAdm(PBSUtils.getRandomCase(admValue))
}
bidder.setResponse(bidRequest.id, bidResponse)

and: "Save account with enabled response correction module"
def accountWithResponseCorrectionModule = accountConfigWithResponseCorrectionModule(bidRequest)
accountDao.save(accountWithResponseCorrectionModule)

when: "PBS processes auction request"
def response = pbsServiceWithResponseCorrectionModule.sendAuctionRequest(bidRequest)

then: "PBS should emit log"
def logsByTime = pbsServiceWithResponseCorrectionModule.getLogsByTime(start)
def bidId = bidResponse.seatbid[0].bid[0].id
def responseCorrection = getLogsByText(logsByTime, bidId)
assert responseCorrection.size() == 1
assert responseCorrection.any {
it.contains("Bid $bidId of bidder generic: changing media type to banner" as String)
}

and: "Response should contain seatBid"
assert response.seatbid.size() == 1

and: "Response should contain single seatBid with proper media type"
assert response.seatbid.bid.ext.prebid.type.flatten() == [BANNER]

and: "Response should contain single seatBid with proper meta media type"
assert response.seatbid.bid.ext.prebid.meta.mediaType.flatten() == [VIDEO.value]

and: "Response shouldn't contain errors"
assert !response.ext.errors

and: "Response shouldn't contain warnings"
assert !response.ext.warnings

where:
admValue << [
"<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST${PBSUtils.randomString}",
"<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST",
"<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST>",
"<${PBSUtils.randomString}VAST${' ' * PBSUtils.getRandomNumber(1, OPTIMAL_MAX_LENGTH)}"
]
}

def "PBS should modify response when requested #mediaType impression respond with adm VAST keyword"() {
Expand All @@ -365,7 +430,7 @@ class ResponseCorrectionSpec extends ModuleBaseSpec {

and: "Set bidder response"
def bidResponse = BidResponse.getDefaultBidResponse(bidRequest).tap {
seatbid[0].bid[0].setAdm(PBSUtils.getRandomCase("<${PBSUtils.randomString}VAST${PBSUtils.randomString}"))
seatbid[0].bid[0].setAdm(PBSUtils.getRandomCase(admValue))
}
bidder.setResponse(bidRequest.id, bidResponse)

Expand All @@ -376,7 +441,7 @@ class ResponseCorrectionSpec extends ModuleBaseSpec {
when: "PBS processes auction request"
def response = pbsServiceWithResponseCorrectionModule.sendAuctionRequest(bidRequest)

then: "PBS shouldn't emit log"
then: "PBS should emit log"
def logsByTime = pbsServiceWithResponseCorrectionModule.getLogsByTime(start)
def bidId = bidResponse.seatbid[0].bid[0].id
def responseCorrection = getLogsByText(logsByTime, bidId)
Expand All @@ -401,7 +466,16 @@ class ResponseCorrectionSpec extends ModuleBaseSpec {
assert !response.ext.warnings

where:
mediaType << [BANNER, AUDIO, NATIVE]
mediaType | admValue
BANNER | "${PBSUtils.randomString}<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST${PBSUtils.randomString}"
BANNER | "<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST${' ' * PBSUtils.getRandomNumber(1, OPTIMAL_MAX_LENGTH)}"
BANNER | "<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}}VAST${' ' * PBSUtils.getRandomNumber(1, OPTIMAL_MAX_LENGTH)}${PBSUtils.randomString}"
AUDIO | "${PBSUtils.randomString}<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST${PBSUtils.randomString}"
AUDIO | "<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST${' ' * PBSUtils.getRandomNumber(1, OPTIMAL_MAX_LENGTH)}"
AUDIO | "<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}}VAST${' ' * PBSUtils.getRandomNumber(1, OPTIMAL_MAX_LENGTH)}${PBSUtils.randomString}"
NATIVE | "${PBSUtils.randomString}<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST${PBSUtils.randomString}"
NATIVE | "<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}VAST${' ' * PBSUtils.getRandomNumber(1, OPTIMAL_MAX_LENGTH)}"
NATIVE | "<${' ' * PBSUtils.getRandomNumber(0, OPTIMAL_MAX_LENGTH)}}VAST${' ' * PBSUtils.getRandomNumber(1, OPTIMAL_MAX_LENGTH)}${PBSUtils.randomString}"
}

def "PBS shouldn't modify response meta.mediaType to video and emit logs when requested impression with video and adm obj with asset"() {
Expand Down
Loading