Provide bid rejected reason to losing bidders.
Allow scoreAd() return an extra string field 'rejectReason', which tells why a bid is rejected. Its value is case sensitive. A bidder's script can use placeholder ${rejectReason} in its debugging loss report URL's query string, to get the reject reason. If score > 0, the 'rejectReason' value will be ignored (set to default 'not-available') even if there is one from scoreAd(). Currently component sellers which participate in a top level auction and act as bidders do not get top level's reject reasons. Fixed: b/232945640 Bug: b/232945640 Change-Id: Idc0a270252241475863f28e0c212453fef9b29dc Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3661960 Reviewed-by: Matt Menke <mmenke@chromium.org> Commit-Queue: Qingxin Wu <qingxinwu@google.com> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Cr-Commit-Position: refs/heads/main@{#1049741}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
4ed53038e0
commit
d225f2c3dd
content
browser
services
auction_worklet
@ -169,7 +169,8 @@ std::string MakeBidScript(const url::Origin& seller,
|
||||
const std::string& signal_val = "",
|
||||
bool report_post_auction_signals = false,
|
||||
const std::string& debug_loss_report_url = "",
|
||||
const std::string& debug_win_report_url = "") {
|
||||
const std::string& debug_win_report_url = "",
|
||||
bool report_reject_reason = false) {
|
||||
// TODO(morlovich): Use JsReplace.
|
||||
constexpr char kBidScript[] = R"(
|
||||
const seller = "%s";
|
||||
@ -180,6 +181,7 @@ std::string MakeBidScript(const url::Origin& seller,
|
||||
const interestGroupName = "%s";
|
||||
const hasSignals = %s;
|
||||
const reportPostAuctionSignals = %s;
|
||||
const reportRejectReason = %s;
|
||||
const postAuctionSignalsPlaceholder = "%s";
|
||||
let debugLossReportUrl = "%s";
|
||||
let debugWinReportUrl = "%s";
|
||||
@ -284,6 +286,10 @@ std::string MakeBidScript(const url::Origin& seller,
|
||||
if (debugLossReportUrl) {
|
||||
if (reportPostAuctionSignals)
|
||||
debugLossReportUrl += postAuctionSignalsPlaceholder;
|
||||
if (reportRejectReason) {
|
||||
debugLossReportUrl += reportPostAuctionSignals ? '&' : '?';
|
||||
debugLossReportUrl += 'rejectReason=${rejectReason}';
|
||||
}
|
||||
forDebuggingOnly.reportAdAuctionLoss(debugLossReportUrl);
|
||||
}
|
||||
if (debugWinReportUrl) {
|
||||
@ -387,8 +393,9 @@ std::string MakeBidScript(const url::Origin& seller,
|
||||
num_ad_components, interest_group_owner.Serialize().c_str(),
|
||||
interest_group_name.c_str(), has_signals ? "true" : "false",
|
||||
report_post_auction_signals ? "true" : "false",
|
||||
kPostAuctionSignalsPlaceholder, debug_loss_report_url.c_str(),
|
||||
debug_win_report_url.c_str(), signal_key.c_str(), signal_val.c_str());
|
||||
report_reject_reason ? "true" : "false", kPostAuctionSignalsPlaceholder,
|
||||
debug_loss_report_url.c_str(), debug_win_report_url.c_str(),
|
||||
signal_key.c_str(), signal_val.c_str());
|
||||
}
|
||||
|
||||
// This can be appended to the standard script to override the function.
|
||||
@ -537,8 +544,7 @@ std::string MakeDecisionScript(
|
||||
if (reportPostAuctionSignals)
|
||||
debugReportUrl += postAuctionSignalsPlaceholder;
|
||||
if (reportTopLevelPostAuctionSignals) {
|
||||
if (reportPostAuctionSignals)
|
||||
debugReportUrl += "&";
|
||||
debugReportUrl += reportPostAuctionSignals ? '&' : '?';
|
||||
debugReportUrl += topLevelPostAuctionSignalsPlaceholder;
|
||||
}
|
||||
// Only add key "bid=" to the report URL when report post auction signals
|
||||
@ -655,23 +661,13 @@ std::string MakeAuctionScriptNoReportUrl(
|
||||
bool report_post_auction_signals = false,
|
||||
const std::string& debug_loss_report_url = "",
|
||||
const std::string& debug_win_report_url = "") {
|
||||
return MakeDecisionScript(
|
||||
decision_logic_url,
|
||||
/*send_report_url=*/absl::nullopt,
|
||||
/*bid_from_component_auction_wins=*/false,
|
||||
/*report_post_auction_signals=*/report_post_auction_signals,
|
||||
debug_loss_report_url, debug_win_report_url);
|
||||
return MakeDecisionScript(decision_logic_url,
|
||||
/*send_report_url=*/absl::nullopt,
|
||||
/*bid_from_component_auction_wins=*/false,
|
||||
report_post_auction_signals, debug_loss_report_url,
|
||||
debug_win_report_url);
|
||||
}
|
||||
|
||||
const char kAuctionScriptRejects2[] = R"(
|
||||
function scoreAd(adMetadata, bid, auctionConfig, browserSignals) {
|
||||
privateAggregation.sendHistogramReport({bucket: 5, value: 6});
|
||||
if (bid === 2)
|
||||
return -1;
|
||||
return bid + 1;
|
||||
}
|
||||
)";
|
||||
|
||||
const char kBasicReportResult[] = R"(
|
||||
function reportResult(auctionConfig, browserSignals) {
|
||||
privateAggregation.sendHistogramReport({bucket: 7, value: 8});
|
||||
@ -683,8 +679,18 @@ const char kBasicReportResult[] = R"(
|
||||
}
|
||||
)";
|
||||
|
||||
std::string MakeAuctionScriptReject2() {
|
||||
return std::string(kAuctionScriptRejects2) + kBasicReportResult;
|
||||
std::string MakeAuctionScriptReject2(
|
||||
const std::string& reject_reason = "not-available") {
|
||||
constexpr char kAuctionScriptRejects2[] = R"(
|
||||
function scoreAd(adMetadata, bid, auctionConfig, browserSignals) {
|
||||
privateAggregation.sendHistogramReport({bucket: 5, value: 6});
|
||||
if (bid === 2)
|
||||
return {desirability: -1, rejectReason: '%s'};
|
||||
return bid + 1;
|
||||
}
|
||||
)";
|
||||
return base::StringPrintf(kAuctionScriptRejects2, reject_reason.c_str()) +
|
||||
kBasicReportResult;
|
||||
}
|
||||
|
||||
std::string MakeAuctionScriptReject1And2WithDebugReporting(
|
||||
@ -695,15 +701,26 @@ std::string MakeAuctionScriptReject1And2WithDebugReporting(
|
||||
const debugWinReportUrl = "%s";
|
||||
function scoreAd(adMetadata, bid, auctionConfig, browserSignals) {
|
||||
let result = bid + 1;
|
||||
if (bid === 1 || bid === 2)
|
||||
let rejectReason = "not-available";
|
||||
if (bid === 1) {
|
||||
result = -1;
|
||||
rejectReason = 'invalid-bid';
|
||||
} else if (bid === 2) {
|
||||
result = -1;
|
||||
rejectReason = 'bid-below-auction-floor';
|
||||
}
|
||||
|
||||
if (debugLossReportUrl) {
|
||||
forDebuggingOnly.reportAdAuctionLoss(
|
||||
debugLossReportUrl + '&bid=' + bid);
|
||||
}
|
||||
if (debugWinReportUrl)
|
||||
forDebuggingOnly.reportAdAuctionWin(debugWinReportUrl + "&bid=" + bid);
|
||||
return result;
|
||||
return {
|
||||
desirability: result,
|
||||
allowComponentAuction: true,
|
||||
rejectReason: rejectReason
|
||||
};
|
||||
}
|
||||
)";
|
||||
return base::StringPrintf(kReject1And2WithDebugReporting,
|
||||
@ -819,9 +836,11 @@ const GURL ReportWinUrl(
|
||||
|
||||
// Returns a report URL with given parameters for forDebuggingOnly win/loss
|
||||
// report APIs, with post auction signals included in the URL.
|
||||
const GURL DebugReportUrl(const std::string& url,
|
||||
const PostAuctionSignals& signals,
|
||||
absl::optional<double> bid = absl::nullopt) {
|
||||
const GURL DebugReportUrl(
|
||||
const std::string& url,
|
||||
const PostAuctionSignals& signals,
|
||||
absl::optional<double> bid = absl::nullopt,
|
||||
absl::optional<std::string> reject_reason = absl::nullopt) {
|
||||
// Post auction signals needs to be consistent with
|
||||
// `kPostAuctionSignalsPlaceholder`. Only keeps integer part of bid values for
|
||||
// simplicity for now.
|
||||
@ -834,6 +853,11 @@ const GURL DebugReportUrl(const std::string& url,
|
||||
signals.made_winning_bid ? "true" : "false",
|
||||
signals.highest_scoring_other_bid,
|
||||
signals.made_highest_scoring_other_bid ? "true" : "false");
|
||||
if (reject_reason.has_value()) {
|
||||
report_url_string.append(
|
||||
base::StringPrintf("&rejectReason=%s", reject_reason.value().c_str()));
|
||||
}
|
||||
|
||||
if (bid.has_value()) {
|
||||
return GURL(base::StringPrintf("%s&bid=%.0f", report_url_string.c_str(),
|
||||
bid.value()));
|
||||
@ -5938,6 +5962,8 @@ TEST_F(AuctionRunnerTest, BidderCrashBeforeBidding) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/11,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -6036,6 +6062,8 @@ TEST_F(AuctionRunnerTest, WinningBidderCrashWhileReporting) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/11,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -6055,6 +6083,8 @@ TEST_F(AuctionRunnerTest, WinningBidderCrashWhileReporting) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -6131,8 +6161,7 @@ TEST_F(AuctionRunnerTest, ForDebuggingOnlyReporting) {
|
||||
kBidder2DebugLossReportUrl, kBidder2DebugWinReportUrl));
|
||||
auction_worklet::AddJavascriptResponse(
|
||||
&url_loader_factory_, kSellerUrl,
|
||||
MakeAuctionScript(/*report_post_auction_signals=*/false,
|
||||
GURL("https://adstuff.publisher1.com/auction.js"),
|
||||
MakeAuctionScript(/*report_post_auction_signals=*/false, kSellerUrl,
|
||||
kSellerDebugLossReportBaseUrl,
|
||||
kSellerDebugWinReportBaseUrl));
|
||||
|
||||
@ -6202,6 +6231,8 @@ TEST_F(AuctionRunnerTest, SellerCrash) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -6216,6 +6247,8 @@ TEST_F(AuctionRunnerTest, SellerCrash) {
|
||||
std::move(score_ad_params2.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/11,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -6330,6 +6363,8 @@ TEST_F(AuctionRunnerTest, ComponentAuctionOneBidderCrashesBeforeBidding) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/3,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParams::New(
|
||||
/*ad=*/"null",
|
||||
/*bid=*/0,
|
||||
@ -6351,6 +6386,8 @@ TEST_F(AuctionRunnerTest, ComponentAuctionOneBidderCrashesBeforeBidding) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/4,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -6449,6 +6486,8 @@ TEST_F(AuctionRunnerTest, ComponentAuctionComponentSellersReportResultFails) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/3,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParams::New(
|
||||
/*ad=*/"null",
|
||||
/*bid=*/0,
|
||||
@ -6470,6 +6509,8 @@ TEST_F(AuctionRunnerTest, ComponentAuctionComponentSellersReportResultFails) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/4,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -6676,7 +6717,10 @@ TEST_F(AuctionRunnerTest, ComponentAuctionComponentSellerBadBidParams) {
|
||||
EXPECT_EQ(2, score_ad_params.bid);
|
||||
mojo::Remote<auction_worklet::mojom::ScoreAdClient>(
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(/*score=*/3, test_case.params.Clone(),
|
||||
->OnScoreAdComplete(/*score=*/3,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
test_case.params.Clone(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
/*debug_loss_report_url=*/absl::nullopt,
|
||||
@ -6735,6 +6779,8 @@ TEST_F(AuctionRunnerTest, TopLevelSellerBadBidParams) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/3,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParams::New(
|
||||
/*ad=*/"null",
|
||||
/*bid=*/0,
|
||||
@ -6805,6 +6851,8 @@ TEST_F(AuctionRunnerTest, NullAdComponents) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/11,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -6902,6 +6950,8 @@ TEST_F(AuctionRunnerTest, AdComponentsLimit) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/11,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -7139,6 +7189,8 @@ TEST_F(AuctionRunnerTest, BadSellerReportUrl) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -7198,6 +7250,8 @@ TEST_F(AuctionRunnerTest, BadSellerBeaconUrl) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -7267,6 +7321,8 @@ TEST_F(AuctionRunnerTest, BadComponentSellerReportUrl) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParams::New(
|
||||
/*ad=*/"null",
|
||||
/*bid=*/0,
|
||||
@ -7285,6 +7341,8 @@ TEST_F(AuctionRunnerTest, BadComponentSellerReportUrl) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -7354,6 +7412,8 @@ TEST_F(AuctionRunnerTest, BadBidderReportUrl) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -7417,6 +7477,8 @@ TEST_F(AuctionRunnerTest, BadBidderBeaconUrl) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -7485,6 +7547,8 @@ TEST_F(AuctionRunnerTest, DestroyBidderWorkletWithoutBid) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/11,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -7550,6 +7614,8 @@ TEST_F(AuctionRunnerTest, Tie) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -7567,6 +7633,8 @@ TEST_F(AuctionRunnerTest, Tie) {
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -7701,6 +7769,8 @@ TEST_F(AuctionRunnerTest, WorkletOrder) {
|
||||
std::move(score_ad_params1.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/bidder1_wins ? 11 : 9,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::
|
||||
ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
@ -7714,15 +7784,18 @@ TEST_F(AuctionRunnerTest, WorkletOrder) {
|
||||
case Event::kBid2Scored:
|
||||
mojo::Remote<auction_worklet::mojom::ScoreAdClient>(
|
||||
std::move(score_ad_params2.score_ad_client))
|
||||
->OnScoreAdComplete(/*score=*/10,
|
||||
auction_worklet::mojom::
|
||||
ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
/*debug_loss_report_url=*/absl::nullopt,
|
||||
/*debug_win_report_url=*/absl::nullopt,
|
||||
/*pa_requests=*/{},
|
||||
/*errors=*/{});
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::
|
||||
ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
/*debug_loss_report_url=*/absl::nullopt,
|
||||
/*debug_win_report_url=*/absl::nullopt,
|
||||
/*pa_requests=*/{},
|
||||
/*errors=*/{});
|
||||
// Wait for the AuctionRunner to receive the score.
|
||||
task_environment_.RunUntilIdle();
|
||||
break;
|
||||
@ -9546,14 +9619,16 @@ TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
kBidder1, kBidder1Name,
|
||||
/*has_signals=*/false, "k1", "a",
|
||||
/*report_post_auction_signals=*/true,
|
||||
kBidder1DebugLossReportUrl, kBidder1DebugWinReportUrl));
|
||||
kBidder1DebugLossReportUrl, kBidder1DebugWinReportUrl,
|
||||
/*report_reject_reason=*/true));
|
||||
auction_worklet::AddJavascriptResponse(
|
||||
&url_loader_factory_, kBidder2Url,
|
||||
MakeBidScript(kSeller, "2", "https://ad2.com/", /*num_ad_components=*/2,
|
||||
kBidder2, kBidder2Name,
|
||||
/*has_signals=*/false, "l2", "b",
|
||||
/*report_post_auction_signals=*/true,
|
||||
kBidder2DebugLossReportUrl, kBidder2DebugWinReportUrl));
|
||||
kBidder2DebugLossReportUrl, kBidder2DebugWinReportUrl,
|
||||
/*report_reject_reason=*/true));
|
||||
auction_worklet::AddJavascriptResponse(
|
||||
&url_loader_factory_, kSellerUrl,
|
||||
MakeAuctionScriptReject1And2WithDebugReporting(
|
||||
@ -9571,8 +9646,10 @@ TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
EXPECT_THAT(
|
||||
res.debug_loss_report_urls,
|
||||
testing::UnorderedElementsAre(
|
||||
DebugReportUrl(kBidder1DebugLossReportUrl, PostAuctionSignals()),
|
||||
DebugReportUrl(kBidder2DebugLossReportUrl, PostAuctionSignals()),
|
||||
DebugReportUrl(kBidder1DebugLossReportUrl, PostAuctionSignals(),
|
||||
/*bid=*/absl::nullopt, "invalid-bid"),
|
||||
DebugReportUrl(kBidder2DebugLossReportUrl, PostAuctionSignals(),
|
||||
/*bid=*/absl::nullopt, "bid-below-auction-floor"),
|
||||
DebugReportUrl(kSellerDebugLossReportBaseUrl, PostAuctionSignals(),
|
||||
/*bid=*/1),
|
||||
DebugReportUrl(kSellerDebugLossReportBaseUrl, PostAuctionSignals(),
|
||||
@ -9706,7 +9783,10 @@ TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
/*bid=*/2)));
|
||||
}
|
||||
|
||||
// Like above test, but top-level seller rejects all bidders.
|
||||
// Test debug loss reporting in an auction with no winner. Component bidder 1 is
|
||||
// rejected by component seller, and component bidder 2 is rejected by top-level
|
||||
// seller. Component bidders get component auction's reject reason but not the
|
||||
// top-level auction's.
|
||||
TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
ForDebuggingOnlyReportingComponentAuctionNoWinner) {
|
||||
interest_group_buyers_.emplace();
|
||||
@ -9715,21 +9795,17 @@ TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
CreateAuctionConfig(kComponentSeller1Url, {{kBidder1}}));
|
||||
auction_worklet::AddJavascriptResponse(
|
||||
&url_loader_factory_, kComponentSeller1Url,
|
||||
MakeDecisionScript(
|
||||
kComponentSeller1Url,
|
||||
/*send_report_url=*/GURL("https://component1-report.test/"),
|
||||
/*bid_from_component_auction_wins=*/false,
|
||||
/*report_post_auction_signals=*/true,
|
||||
/*debug_loss_report_url=*/"https://component1-loss-reporting.test/",
|
||||
/*debug_win_report_url=*/"https://component1-win-reporting.test/",
|
||||
/*report_top_level_post_auction_signals*/ true));
|
||||
MakeAuctionScriptReject1And2WithDebugReporting(
|
||||
"https://component1-loss-reporting.test/?",
|
||||
"https://component1-win-reporting.test/?"));
|
||||
auction_worklet::AddJavascriptResponse(
|
||||
&url_loader_factory_, kBidder1Url,
|
||||
MakeBidScript(kComponentSeller1, "1", "https://ad1.com/",
|
||||
/*num_ad_components=*/2, kBidder1, kBidder1Name,
|
||||
/*has_signals=*/true, "k1", "a",
|
||||
/*report_post_auction_signals=*/true,
|
||||
kBidder1DebugLossReportUrl, kBidder1DebugWinReportUrl));
|
||||
kBidder1DebugLossReportUrl, kBidder1DebugWinReportUrl,
|
||||
/*report_reject_reason=*/true));
|
||||
auction_worklet::AddBidderJsonResponse(
|
||||
&url_loader_factory_,
|
||||
GURL(kBidder1TrustedSignalsUrl.spec() +
|
||||
@ -9755,7 +9831,8 @@ TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
/*num_ad_components=*/2, kBidder2, kBidder2Name,
|
||||
/*has_signals=*/true, "l2", "b",
|
||||
/*report_post_auction_signals=*/true,
|
||||
kBidder2DebugLossReportUrl, kBidder2DebugWinReportUrl));
|
||||
kBidder2DebugLossReportUrl, kBidder2DebugWinReportUrl,
|
||||
/*report_reject_reason=*/true));
|
||||
auction_worklet::AddBidderJsonResponse(
|
||||
&url_loader_factory_,
|
||||
GURL(kBidder2TrustedSignalsUrl.spec() +
|
||||
@ -9775,7 +9852,11 @@ function scoreAd(adMetadata, bid, auctionConfig, trustedScoringSignals,
|
||||
// While not setting `allowComponentAuction` will also reject the ad, it
|
||||
// also prevents loss reports and adds an error message, so need to set
|
||||
// it to true.
|
||||
return {desirability: 0, allowComponentAuction: true};
|
||||
return {
|
||||
desirability: 0,
|
||||
allowComponentAuction: true,
|
||||
rejectReason: "bid-below-auction-floor"
|
||||
};
|
||||
}
|
||||
)",
|
||||
kPostAuctionSignalsPlaceholder,
|
||||
@ -9787,34 +9868,27 @@ function scoreAd(adMetadata, bid, auctionConfig, trustedScoringSignals,
|
||||
// No interest group won the auction.
|
||||
EXPECT_FALSE(result_.ad_url);
|
||||
|
||||
// Component bidder 1 rejected by component auction gets its reject reason
|
||||
// "invalid-bid". Component bidders don't get the top-level auction's reject
|
||||
// reason.
|
||||
EXPECT_THAT(
|
||||
result_.debug_loss_report_urls,
|
||||
testing::UnorderedElementsAre(
|
||||
DebugReportUrl(kBidder1DebugLossReportUrl,
|
||||
PostAuctionSignals(
|
||||
/*winning_bid=*/1,
|
||||
/*made_winning_bid=*/true,
|
||||
/*winning_bid=*/0,
|
||||
/*made_winning_bid=*/false,
|
||||
/*highest_scoring_other_bid=*/0,
|
||||
/*made_highest_scoring_other_bid=*/false)),
|
||||
ComponentSellerDebugReportUrl(
|
||||
"https://component1-loss-reporting.test/",
|
||||
/*signals=*/
|
||||
PostAuctionSignals(/*winning_bid=*/1,
|
||||
/*made_winning_bid=*/true,
|
||||
/*highest_scoring_other_bid=*/0,
|
||||
/*made_highest_scoring_other_bid=*/false),
|
||||
/*top_level_signals=*/
|
||||
PostAuctionSignals(),
|
||||
/*bid=*/1),
|
||||
DebugReportUrl("https://top-seller-loss-reporting.test/",
|
||||
PostAuctionSignals(),
|
||||
/*bid=*/1),
|
||||
/*made_highest_scoring_other_bid=*/false),
|
||||
/*bid=*/absl::nullopt, "invalid-bid"),
|
||||
GURL("https://component1-loss-reporting.test/?&bid=1"),
|
||||
DebugReportUrl(kBidder2DebugLossReportUrl,
|
||||
PostAuctionSignals(
|
||||
/*winning_bid=*/2,
|
||||
/*made_winning_bid=*/true,
|
||||
/*highest_scoring_other_bid=*/0,
|
||||
/*made_highest_scoring_other_bid=*/false)),
|
||||
/*made_highest_scoring_other_bid=*/false),
|
||||
/*bid=*/absl::nullopt, "not-available"),
|
||||
ComponentSellerDebugReportUrl(
|
||||
"https://component2-loss-reporting.test/",
|
||||
/*signals=*/
|
||||
@ -10097,6 +10171,8 @@ TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -10160,6 +10236,8 @@ TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
std::move(score_ad_params.score_ad_client))
|
||||
->OnScoreAdComplete(
|
||||
/*score=*/10,
|
||||
/*reject_reason=*/
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*scoring_signals_data_version=*/0,
|
||||
/*has_scoring_signals_data_version=*/false,
|
||||
@ -10343,8 +10421,231 @@ TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
GURL("https://seller0.test/win/11")));
|
||||
}
|
||||
|
||||
// Enable and test forDebuggingOnly.reportAdAuctionLoss() and
|
||||
// forDebuggingOnly.reportAdAuctionWin() APIs.
|
||||
// Reject reason returned by scoreAd() for a rejected bid can be reported to the
|
||||
// bidder through its debug loss report URL.
|
||||
TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
RejectedBidGetsRejectReason) {
|
||||
for (const std::string& reject_reason :
|
||||
{"not-available", "invalid-bid", "bid-below-auction-floor",
|
||||
"pending-approval-by-exchange", "disapproved-by-exchange",
|
||||
"blocked-by-publisher", "language-exclusions", "category-exclusions"}) {
|
||||
auction_worklet::AddJavascriptResponse(
|
||||
&url_loader_factory_, kBidder1Url,
|
||||
MakeBidScript(kSeller, "1", "https://ad1.com/", /*num_ad_components=*/2,
|
||||
kBidder1, kBidder1Name,
|
||||
/*has_signals=*/false, "k1", "a",
|
||||
/*report_post_auction_signals=*/false,
|
||||
kBidder1DebugLossReportUrl, kBidder1DebugWinReportUrl,
|
||||
/*report_reject_reason=*/true));
|
||||
// Bidder 2 will get a negative score from scoreAd().
|
||||
auction_worklet::AddJavascriptResponse(
|
||||
&url_loader_factory_, kBidder2Url,
|
||||
MakeBidScript(kSeller, "2", "https://ad2.com/", /*num_ad_components=*/2,
|
||||
kBidder2, kBidder2Name,
|
||||
/*has_signals=*/false, "l2", "b",
|
||||
/*report_post_auction_signals=*/false,
|
||||
kBidder2DebugLossReportUrl, kBidder2DebugWinReportUrl,
|
||||
/*report_reject_reason=*/true));
|
||||
auction_worklet::AddJavascriptResponse(
|
||||
&url_loader_factory_, kSellerUrl,
|
||||
MakeAuctionScriptReject2(reject_reason));
|
||||
|
||||
const Result& res = RunStandardAuction();
|
||||
// Bidder 1 won the auction.
|
||||
EXPECT_EQ(InterestGroupKey(kBidder1, kBidder1Name),
|
||||
result_.winning_group_id);
|
||||
EXPECT_EQ(GURL("https://ad1.com/"), res.ad_url);
|
||||
|
||||
EXPECT_EQ(1u, res.debug_loss_report_urls.size());
|
||||
// Seller rejected bidder 2 and returned the reject reason which were then
|
||||
// reported to bidder 2 through its loss report URL.
|
||||
EXPECT_THAT(res.debug_loss_report_urls,
|
||||
testing::UnorderedElementsAre(base::StringPrintf(
|
||||
"https://bidder2-debug-loss-reporting.com/"
|
||||
"?rejectReason=%s",
|
||||
reject_reason.c_str())));
|
||||
|
||||
EXPECT_EQ(1u, res.debug_win_report_urls.size());
|
||||
EXPECT_THAT(res.debug_win_report_urls,
|
||||
testing::UnorderedElementsAre(kBidder1DebugWinReportUrl));
|
||||
}
|
||||
}
|
||||
|
||||
// Reject reason returned by scoreAd() for a bid whose score is positive is
|
||||
// ignored and will not be reported to the bidder.
|
||||
TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
rejectReasonIgnoredForPositiveBid) {
|
||||
auction_worklet::AddJavascriptResponse(
|
||||
&url_loader_factory_, kBidder1Url,
|
||||
MakeBidScript(kSeller, "1", "https://ad1.com/", /*num_ad_components=*/2,
|
||||
kBidder1, kBidder1Name,
|
||||
/*has_signals=*/false, "k1", "a",
|
||||
/*report_post_auction_signals=*/false,
|
||||
kBidder1DebugLossReportUrl, kBidder1DebugWinReportUrl,
|
||||
/*report_reject_reason=*/true));
|
||||
|
||||
auction_worklet::AddJavascriptResponse(
|
||||
&url_loader_factory_, kBidder2Url,
|
||||
MakeBidScript(kSeller, "3", "https://ad2.com/", /*num_ad_components=*/2,
|
||||
kBidder2, kBidder2Name,
|
||||
/*has_signals=*/false, "l2", "b",
|
||||
/*report_post_auction_signals=*/false,
|
||||
kBidder2DebugLossReportUrl, kBidder2DebugWinReportUrl,
|
||||
/*report_reject_reason=*/true));
|
||||
auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
|
||||
MakeAuctionScriptReject2());
|
||||
|
||||
const Result& res = RunStandardAuction();
|
||||
// Bidder 2 won the auction.
|
||||
EXPECT_EQ(InterestGroupKey(kBidder2, kBidder2Name), result_.winning_group_id);
|
||||
EXPECT_EQ(GURL("https://ad2.com/"), res.ad_url);
|
||||
|
||||
EXPECT_EQ(1u, res.debug_loss_report_urls.size());
|
||||
// Reject reason returned by scoreAd() for bidder 1 should be ignored and
|
||||
// reported as "not-available" in debug loss report URL, because the bid gets
|
||||
// a positive score thus not rejected by seller.
|
||||
EXPECT_THAT(
|
||||
res.debug_loss_report_urls,
|
||||
testing::UnorderedElementsAre("https://bidder1-debug-loss-reporting.com/"
|
||||
"?rejectReason=not-available"));
|
||||
|
||||
EXPECT_EQ(1u, res.debug_win_report_urls.size());
|
||||
EXPECT_THAT(res.debug_win_report_urls,
|
||||
testing::UnorderedElementsAre(kBidder2DebugWinReportUrl));
|
||||
}
|
||||
|
||||
// Only bidders' debug loss report URLs support macro ${rejectReason}.
|
||||
// Bidders' debug win report URLs and sellers' debug loss/win report URLs does
|
||||
// not.
|
||||
TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
rejectReasonInBidderDebugLossReportOnly) {
|
||||
const char kBidder1Script[] = R"(
|
||||
function generateBid(interestGroup, auctionSignals, perBuyerSignals,
|
||||
trustedBiddingSignals, browserSignals) {
|
||||
forDebuggingOnly.reportAdAuctionLoss(
|
||||
'https://bidder1-debug-loss-reporting.com/?reason=${rejectReason}');
|
||||
forDebuggingOnly.reportAdAuctionWin(
|
||||
'https://bidder1-debug-win-reporting.com/?reason=${rejectReason}');
|
||||
return {
|
||||
bid: 1,
|
||||
render: interestGroup.ads[0].renderUrl
|
||||
};
|
||||
}
|
||||
|
||||
// Prevent an error about this method not existing.
|
||||
function reportWin() {}
|
||||
)";
|
||||
|
||||
const char kBidder2Script[] = R"(
|
||||
function generateBid(interestGroup, auctionSignals, perBuyerSignals,
|
||||
trustedBiddingSignals, browserSignals) {
|
||||
forDebuggingOnly.reportAdAuctionLoss(
|
||||
'https://bidder2-debug-loss-reporting.com/?reason=${rejectReason}');
|
||||
forDebuggingOnly.reportAdAuctionWin(
|
||||
'https://bidder2-debug-win-reporting.com/?reason=${rejectReason}');
|
||||
return {
|
||||
bid: 2,
|
||||
render: interestGroup.ads[0].renderUrl
|
||||
};
|
||||
}
|
||||
|
||||
// Prevent an error about this method not existing.
|
||||
function reportWin() {}
|
||||
)";
|
||||
|
||||
// Desirability is -1 if bid is 1, otherwise is bid.
|
||||
const char kSellerScript[] = R"(
|
||||
function scoreAd(adMetadata, bid, auctionConfig, trustedScoringSignals,
|
||||
browserSignals) {
|
||||
forDebuggingOnly.reportAdAuctionLoss(
|
||||
'https://seller-debug-loss-reporting.com/?reason=${rejectReason}');
|
||||
forDebuggingOnly.reportAdAuctionWin(
|
||||
'https://seller-debug-win-reporting.com/?reason=${rejectReason}');
|
||||
if (bid == 1) {
|
||||
return {desirability: -1, rejectReason: 'invalid-bid'}
|
||||
} else {
|
||||
return bid;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent an error about this method not existing.
|
||||
function reportResult() {}
|
||||
)";
|
||||
|
||||
auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
|
||||
kBidder1Script);
|
||||
auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder2Url,
|
||||
kBidder2Script);
|
||||
auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
|
||||
kSellerScript);
|
||||
|
||||
const Result& res = RunStandardAuction();
|
||||
// Bidder 2 won the auction.
|
||||
EXPECT_EQ(InterestGroupKey(kBidder2, kBidder2Name), result_.winning_group_id);
|
||||
EXPECT_EQ(GURL("https://ad2.com/"), res.ad_url);
|
||||
|
||||
// Only bidder's debug loss report supports macro ${rejectReason}.
|
||||
EXPECT_EQ(2u, res.debug_loss_report_urls.size());
|
||||
EXPECT_THAT(
|
||||
res.debug_loss_report_urls,
|
||||
testing::UnorderedElementsAre(
|
||||
"https://bidder1-debug-loss-reporting.com/?reason=invalid-bid",
|
||||
"https://seller-debug-loss-reporting.com/"
|
||||
"?reason=${rejectReason}"));
|
||||
EXPECT_EQ(2u, res.debug_win_report_urls.size());
|
||||
EXPECT_THAT(
|
||||
res.debug_win_report_urls,
|
||||
testing::UnorderedElementsAre("https://bidder2-debug-win-reporting.com/"
|
||||
"?reason=${rejectReason}",
|
||||
"https://seller-debug-win-reporting.com/"
|
||||
"?reason=${rejectReason}"));
|
||||
}
|
||||
|
||||
// When scoreAd() does not return a reject reason, report it as "not-available"
|
||||
// in bidder's loss report URL as default.
|
||||
TEST_F(AuctionRunnerBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
SellerNotReturningRejectReason) {
|
||||
const char kBidderScript[] = R"(
|
||||
function generateBid(interestGroup, auctionSignals, perBuyerSignals,
|
||||
trustedBiddingSignals, browserSignals) {
|
||||
forDebuggingOnly.reportAdAuctionLoss(
|
||||
'https://bidder-debug-loss-reporting.com/?reason=${rejectReason}');
|
||||
return {
|
||||
bid: 1,
|
||||
render: interestGroup.ads[0].renderUrl
|
||||
};
|
||||
}
|
||||
|
||||
// Prevent an error about this method not existing.
|
||||
function reportWin() {}
|
||||
)";
|
||||
|
||||
const char kSellerScript[] = R"(
|
||||
function scoreAd(adMetadata, bid, auctionConfig, trustedScoringSignals,
|
||||
browserSignals) {
|
||||
return {desirability: -1};
|
||||
}
|
||||
|
||||
// Prevent an error about this method not existing.
|
||||
function reportResult() {}
|
||||
)";
|
||||
|
||||
auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
|
||||
kBidderScript);
|
||||
auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
|
||||
kSellerScript);
|
||||
|
||||
const Result& res = RunStandardAuction();
|
||||
|
||||
EXPECT_EQ(1u, res.debug_loss_report_urls.size());
|
||||
EXPECT_THAT(
|
||||
res.debug_loss_report_urls,
|
||||
testing::UnorderedElementsAre("https://bidder-debug-loss-reporting.com/"
|
||||
"?reason=not-available"));
|
||||
EXPECT_EQ(0u, res.debug_win_report_urls.size());
|
||||
}
|
||||
|
||||
// Disable private aggregation API.
|
||||
class AuctionRunnerPrivateAggregationAPIDisabledTest
|
||||
: public AuctionRunnerTest {
|
||||
public:
|
||||
|
@ -410,13 +410,15 @@ class InterestGroupAuction::BuyerHelper
|
||||
continue;
|
||||
}
|
||||
if (bid_state->bidder_debug_loss_report_url.has_value()) {
|
||||
// Losing bidders should not get highest_scoring_other_bid and
|
||||
// made_highest_scoring_other_bid signals.
|
||||
// Losing and rejected bidders should not get highest_scoring_other_bid
|
||||
// and made_highest_scoring_other_bid signals.
|
||||
debug_loss_report_urls.emplace_back(FillPostAuctionSignals(
|
||||
std::move(bid_state->bidder_debug_loss_report_url).value(),
|
||||
PostAuctionSignals(signals.winning_bid, signals.made_winning_bid,
|
||||
0.0, false)));
|
||||
0.0, false),
|
||||
/*top_level_signals=*/absl::nullopt, bid_state->reject_reason));
|
||||
}
|
||||
// TODO(qingxinwu): Add reject reason to seller debug loss report as well.
|
||||
if (bid_state->seller_debug_loss_report_url.has_value()) {
|
||||
debug_loss_report_urls.emplace_back(FillPostAuctionSignals(
|
||||
std::move(bid_state->seller_debug_loss_report_url).value(), signals,
|
||||
@ -762,10 +764,10 @@ class InterestGroupAuction::BuyerHelper
|
||||
maybe_bidding_signals_data_version,
|
||||
debug_loss_report_url, debug_win_report_url);
|
||||
if (bid)
|
||||
state->bidder_debug_loss_report_url = std::move(debug_loss_report_url);
|
||||
state->bidder_debug_loss_report_url = debug_loss_report_url;
|
||||
} else {
|
||||
// Bidders who do not bid are allowed to get loss report.
|
||||
state->bidder_debug_loss_report_url = std::move(debug_loss_report_url);
|
||||
state->bidder_debug_loss_report_url = debug_loss_report_url;
|
||||
}
|
||||
|
||||
// Release the worklet. If it wins the auction, it will be requested again
|
||||
@ -775,7 +777,7 @@ class InterestGroupAuction::BuyerHelper
|
||||
if (!bid) {
|
||||
state->EndTracing();
|
||||
} else {
|
||||
state->bidder_debug_win_report_url = std::move(debug_win_report_url);
|
||||
state->bidder_debug_win_report_url = debug_win_report_url;
|
||||
state->made_bid = true;
|
||||
auction_->ScoreBidIfReady(std::move(bid));
|
||||
}
|
||||
@ -1180,10 +1182,43 @@ void InterestGroupAuction::GetInterestGroupsThatBid(
|
||||
}
|
||||
}
|
||||
|
||||
base::StringPiece GetRejectReasonString(
|
||||
const auction_worklet::mojom::RejectReason reject_reason) {
|
||||
base::StringPiece reject_reason_str;
|
||||
switch (reject_reason) {
|
||||
case auction_worklet::mojom::RejectReason::kNotAvailable:
|
||||
reject_reason_str = "not-available";
|
||||
break;
|
||||
case auction_worklet::mojom::RejectReason::kInvalidBid:
|
||||
reject_reason_str = "invalid-bid";
|
||||
break;
|
||||
case auction_worklet::mojom::RejectReason::kBidBelowAuctionFloor:
|
||||
reject_reason_str = "bid-below-auction-floor";
|
||||
break;
|
||||
case auction_worklet::mojom::RejectReason::kPendingApprovalByExchange:
|
||||
reject_reason_str = "pending-approval-by-exchange";
|
||||
break;
|
||||
case auction_worklet::mojom::RejectReason::kDisapprovedByExchange:
|
||||
reject_reason_str = "disapproved-by-exchange";
|
||||
break;
|
||||
case auction_worklet::mojom::RejectReason::kBlockedByPublisher:
|
||||
reject_reason_str = "blocked-by-publisher";
|
||||
break;
|
||||
case auction_worklet::mojom::RejectReason::kLanguageExclusions:
|
||||
reject_reason_str = "language-exclusions";
|
||||
break;
|
||||
case auction_worklet::mojom::RejectReason::kCategoryExclusions:
|
||||
reject_reason_str = "category-exclusions";
|
||||
break;
|
||||
}
|
||||
return reject_reason_str;
|
||||
}
|
||||
|
||||
GURL InterestGroupAuction::FillPostAuctionSignals(
|
||||
const GURL& url,
|
||||
const PostAuctionSignals& signals,
|
||||
const absl::optional<PostAuctionSignals>& top_level_signals) {
|
||||
const absl::optional<PostAuctionSignals>& top_level_signals,
|
||||
const absl::optional<auction_worklet::mojom::RejectReason> reject_reason) {
|
||||
// TODO(qingxinwu): Round `winning_bid` and `highest_scoring_other_bid` to two
|
||||
// most-significant digits. Maybe same to corresponding browser signals of
|
||||
// reportWin()/reportResult().
|
||||
@ -1217,6 +1252,12 @@ GURL InterestGroupAuction::FillPostAuctionSignals(
|
||||
top_level_signals->made_winning_bid ? "true" : "false");
|
||||
}
|
||||
|
||||
if (reject_reason.has_value()) {
|
||||
base::ReplaceSubstringsAfterOffset(
|
||||
&query_string, 0, "${rejectReason}",
|
||||
GetRejectReasonString(reject_reason.value()));
|
||||
}
|
||||
|
||||
GURL::Replacements replacements;
|
||||
replacements.SetQueryStr(query_string);
|
||||
return url.ReplaceComponents(replacements);
|
||||
@ -1671,6 +1712,7 @@ bool InterestGroupAuction::ValidateScoreBidCompleteResult(
|
||||
|
||||
void InterestGroupAuction::OnScoreAdComplete(
|
||||
double score,
|
||||
auction_worklet::mojom::RejectReason reject_reason,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
uint32_t data_version,
|
||||
@ -1719,6 +1761,9 @@ void InterestGroupAuction::OnScoreAdComplete(
|
||||
std::move(debug_loss_report_url);
|
||||
bid->bid_state->seller_debug_win_report_url =
|
||||
std::move(debug_win_report_url);
|
||||
// Ignores reject reason if score > 0.
|
||||
if (score <= 0)
|
||||
bid->bid_state->reject_reason = reject_reason;
|
||||
} else {
|
||||
bid->bid_state->top_level_seller_debug_loss_report_url =
|
||||
std::move(debug_loss_report_url);
|
||||
|
@ -243,6 +243,11 @@ class CONTENT_EXPORT InterestGroupAuction
|
||||
// auction, won it, and was then scored by the top-level seller.
|
||||
absl::optional<GURL> top_level_seller_debug_win_report_url;
|
||||
absl::optional<GURL> top_level_seller_debug_loss_report_url;
|
||||
|
||||
// The reason this bid was rejected by the auction (i.e., reason why score
|
||||
// was non-positive).
|
||||
auction_worklet::mojom::RejectReason reject_reason =
|
||||
auction_worklet::mojom::RejectReason::kNotAvailable;
|
||||
};
|
||||
|
||||
// Result of generated a bid. Contains information that needs to score a bid
|
||||
@ -541,6 +546,7 @@ class CONTENT_EXPORT InterestGroupAuction
|
||||
// auction_worklet::mojom::ScoreAdClient implementation:
|
||||
void OnScoreAdComplete(
|
||||
double score,
|
||||
auction_worklet::mojom::RejectReason reject_reason,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
uint32_t scoring_signals_data_version,
|
||||
@ -638,10 +644,13 @@ class CONTENT_EXPORT InterestGroupAuction
|
||||
// Replaces `${}` placeholders in a debug report URL's query string for post
|
||||
// auction signals if exist. Only replaces unescaped placeholder ${}, but
|
||||
// not escaped placeholder (i.e., %24%7B%7D).
|
||||
static GURL FillPostAuctionSignals(const GURL& url,
|
||||
const PostAuctionSignals& signals,
|
||||
const absl::optional<PostAuctionSignals>&
|
||||
top_level_signals = absl::nullopt);
|
||||
static GURL FillPostAuctionSignals(
|
||||
const GURL& url,
|
||||
const PostAuctionSignals& signals,
|
||||
const absl::optional<PostAuctionSignals>& top_level_signals =
|
||||
absl::nullopt,
|
||||
const absl::optional<auction_worklet::mojom::RejectReason> reject_reason =
|
||||
absl::nullopt);
|
||||
|
||||
// Tracing ID associated with the Auction. A nestable
|
||||
// async "Auction" trace
|
||||
|
@ -54,6 +54,18 @@ struct ComponentAuctionReportResultParams {
|
||||
bool has_modified_bid;
|
||||
};
|
||||
|
||||
// The reason a bid was rejected by an auction.
|
||||
enum RejectReason {
|
||||
kNotAvailable = 0,
|
||||
kInvalidBid = 1,
|
||||
kBidBelowAuctionFloor = 2,
|
||||
kPendingApprovalByExchange = 3,
|
||||
kDisapprovedByExchange = 4,
|
||||
kBlockedByPublisher = 5,
|
||||
kLanguageExclusions = 6,
|
||||
kCategoryExclusions = 7,
|
||||
};
|
||||
|
||||
// Interface for returning ScoreAd results. The advantage of having an interface
|
||||
// is that it makes ScoreAd() calls cancellable, and allows callbacks passed
|
||||
// over the Mojo pipe to be deleted when the Mojo pipe is, to avoid setting off
|
||||
@ -66,6 +78,10 @@ interface ScoreAdClient {
|
||||
// of 0 indicates either an error running the script, or that the script
|
||||
// indicated the bid should not be used.
|
||||
//
|
||||
// `reject_reason` The reason this bid was rejected by the auction (i.e., the
|
||||
// reason why `score` was non-positive). Default to kNotAvailable if not set.
|
||||
// Will be ignored if `score` is positive.
|
||||
//
|
||||
// `component_auction_modified_bid_params` If this is a component seller
|
||||
// worklet, contains parameters to pass to the top-level seller worklet
|
||||
// in place of values from the original bidder worklet's BidderWorkletBid.
|
||||
@ -96,6 +112,7 @@ interface ScoreAdClient {
|
||||
// empty if `score` is positive, nor should it be assumed to be non-empty if
|
||||
// `score` is 0.
|
||||
OnScoreAdComplete(double score,
|
||||
RejectReason reject_reason,
|
||||
ComponentAuctionModifiedBidParams?
|
||||
component_auction_modified_bid_params,
|
||||
uint32 scoring_signals_data_version,
|
||||
@ -160,7 +177,7 @@ interface SellerWorklet {
|
||||
// to use with tracing calls.
|
||||
//
|
||||
// `score_ad_client` When the ScoreAd completes, successfully or not, its
|
||||
// OnScoreAdComplete() method will invoked be invoked with the results.
|
||||
// OnScoreAdComplete() method will be invoked with the results.
|
||||
ScoreAd(string ad_metadata_json,
|
||||
double bid,
|
||||
blink.mojom.AuctionAdConfigNonSharedParams
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@ -261,6 +262,30 @@ bool AddOtherSeller(
|
||||
browser_signals_other_seller->get_component_seller().Serialize());
|
||||
}
|
||||
|
||||
// Converts reject reason string to corresponding mojom enum.
|
||||
absl::optional<mojom::RejectReason> RejectReasonStringToEnum(
|
||||
const std::string& reason) {
|
||||
if (reason == "not-available") {
|
||||
return mojom::RejectReason::kNotAvailable;
|
||||
} else if (reason == "invalid-bid") {
|
||||
return mojom::RejectReason::kInvalidBid;
|
||||
} else if (reason == "bid-below-auction-floor") {
|
||||
return mojom::RejectReason::kBidBelowAuctionFloor;
|
||||
} else if (reason == "pending-approval-by-exchange") {
|
||||
return mojom::RejectReason::kPendingApprovalByExchange;
|
||||
} else if (reason == "disapproved-by-exchange") {
|
||||
return mojom::RejectReason::kDisapprovedByExchange;
|
||||
} else if (reason == "blocked-by-publisher") {
|
||||
return mojom::RejectReason::kBlockedByPublisher;
|
||||
} else if (reason == "language-exclusions") {
|
||||
return mojom::RejectReason::kLanguageExclusions;
|
||||
} else if (reason == "category-exclusions") {
|
||||
return mojom::RejectReason::kCategoryExclusions;
|
||||
}
|
||||
// Invalid (out of range) reject reason.
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
SellerWorklet::SellerWorklet(
|
||||
@ -595,6 +620,7 @@ void SellerWorklet::V8State::ScoreAd(
|
||||
// `scoreAd()` might use them to detect script timeout or failures.
|
||||
PostScoreAdCallbackToUserThread(
|
||||
std::move(callback), /*score=*/0,
|
||||
/*reject_reason=*/mojom::RejectReason::kNotAvailable,
|
||||
/*component_auction_modified_bid_params=*/nullptr,
|
||||
/*scoring_signals_data_version=*/absl::nullopt,
|
||||
/*debug_loss_report_url=*/
|
||||
@ -607,13 +633,14 @@ void SellerWorklet::V8State::ScoreAd(
|
||||
}
|
||||
|
||||
double score;
|
||||
mojom::RejectReason reject_reason = mojom::RejectReason::kNotAvailable;
|
||||
bool allow_component_auction = false;
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params;
|
||||
// Try to parse the result as a number. On success, it's the desirability
|
||||
// score.
|
||||
if (!gin::ConvertFromV8(isolate, score_ad_result, &score)) {
|
||||
// Otherwise, try it must be an object with the desireability score, and
|
||||
// Otherwise, it must be an object with the desireability score, and
|
||||
// potentially other fields as well.
|
||||
if (!score_ad_result->IsObject()) {
|
||||
errors_out.push_back(
|
||||
@ -642,6 +669,30 @@ void SellerWorklet::V8State::ScoreAd(
|
||||
if (!result_dict.Get("allowComponentAuction", &allow_component_auction))
|
||||
allow_component_auction = false;
|
||||
|
||||
v8::Local<v8::Value> reject_reason_value;
|
||||
if (score_ad_object
|
||||
->Get(context, v8_helper_->CreateStringFromLiteral("rejectReason"))
|
||||
.ToLocal(&reject_reason_value) &&
|
||||
!reject_reason_value->IsUndefined()) {
|
||||
if (!reject_reason_value->IsString()) {
|
||||
errors_out.push_back(base::StrCat(
|
||||
{decision_logic_url_.spec(),
|
||||
" rejectReason returned by scoreAd() must be a string."}));
|
||||
} else {
|
||||
std::string reject_reason_str;
|
||||
result_dict.Get("rejectReason", &reject_reason_str);
|
||||
auto reject_reason_opt = RejectReasonStringToEnum(reject_reason_str);
|
||||
|
||||
if (!reject_reason_opt.has_value()) {
|
||||
errors_out.push_back(
|
||||
base::StrCat({decision_logic_url_.spec(),
|
||||
" scoreAd() returned an invalid reject reason."}));
|
||||
} else {
|
||||
reject_reason = reject_reason_opt.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is the seller in a component auction (and thus it was passed a
|
||||
// top-level seller), need to return a
|
||||
// mojom::ComponentAuctionModifiedBidParams.
|
||||
@ -695,7 +746,7 @@ void SellerWorklet::V8State::ScoreAd(
|
||||
// Keep debug report URLs because we want to send debug loss reports if
|
||||
// seller rejected all bids.
|
||||
PostScoreAdCallbackToUserThread(
|
||||
std::move(callback), /*score=*/0,
|
||||
std::move(callback), /*score=*/0, reject_reason,
|
||||
/*component_auction_modified_bid_params=*/nullptr,
|
||||
scoring_signals_data_version,
|
||||
context_recycler.for_debugging_only_bindings()->TakeLossReportUrl(),
|
||||
@ -726,6 +777,7 @@ void SellerWorklet::V8State::ScoreAd(
|
||||
|
||||
PostScoreAdCallbackToUserThread(
|
||||
std::move(callback), score,
|
||||
/*reject_reason=*/mojom::RejectReason::kNotAvailable,
|
||||
std::move(component_auction_modified_bid_params),
|
||||
scoring_signals_data_version,
|
||||
context_recycler.for_debugging_only_bindings()->TakeLossReportUrl(),
|
||||
@ -904,6 +956,7 @@ void SellerWorklet::V8State::PostScoreAdCallbackToUserThreadOnError(
|
||||
PrivateAggregationRequests pa_requests) {
|
||||
PostScoreAdCallbackToUserThread(
|
||||
std::move(callback), /*score=*/0,
|
||||
/*reject_reason=*/mojom::RejectReason::kNotAvailable,
|
||||
/*component_auction_modified_bid_params=*/nullptr,
|
||||
/*scoring_signals_data_version=*/absl::nullopt,
|
||||
/*debug_loss_report_url=*/absl::nullopt,
|
||||
@ -914,6 +967,7 @@ void SellerWorklet::V8State::PostScoreAdCallbackToUserThreadOnError(
|
||||
void SellerWorklet::V8State::PostScoreAdCallbackToUserThread(
|
||||
ScoreAdCallbackInternal callback,
|
||||
double score,
|
||||
mojom::RejectReason reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
absl::optional<uint32_t> scoring_signals_data_version,
|
||||
@ -924,7 +978,7 @@ void SellerWorklet::V8State::PostScoreAdCallbackToUserThread(
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(v8_sequence_checker_);
|
||||
user_thread_->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(std::move(callback), score,
|
||||
base::BindOnce(std::move(callback), score, reject_reason,
|
||||
std::move(component_auction_modified_bid_params),
|
||||
scoring_signals_data_version,
|
||||
std::move(debug_loss_report_url),
|
||||
@ -1081,6 +1135,7 @@ void SellerWorklet::ScoreAdIfReady(ScoreAdTaskList::iterator task) {
|
||||
void SellerWorklet::DeliverScoreAdCallbackOnUserThread(
|
||||
ScoreAdTaskList::iterator task,
|
||||
double score,
|
||||
mojom::RejectReason reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
absl::optional<uint32_t> scoring_signals_data_version,
|
||||
@ -1089,7 +1144,6 @@ void SellerWorklet::DeliverScoreAdCallbackOnUserThread(
|
||||
PrivateAggregationRequests pa_requests,
|
||||
std::vector<std::string> errors) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_);
|
||||
|
||||
if (load_script_error_msg_)
|
||||
errors.insert(errors.begin(), load_script_error_msg_.value());
|
||||
if (task->trusted_scoring_signals_error_msg)
|
||||
@ -1102,7 +1156,7 @@ void SellerWorklet::DeliverScoreAdCallbackOnUserThread(
|
||||
// it does. Only useful if the SellerWorklet object is still in use, so
|
||||
// unclear how useful it would be.
|
||||
task->score_ad_client->OnScoreAdComplete(
|
||||
score, std::move(component_auction_modified_bid_params),
|
||||
score, reject_reason, std::move(component_auction_modified_bid_params),
|
||||
scoring_signals_data_version.value_or(0),
|
||||
scoring_signals_data_version.has_value(), debug_loss_report_url,
|
||||
debug_win_report_url, std::move(pa_requests), std::move(errors));
|
||||
|
@ -195,6 +195,7 @@ class CONTENT_EXPORT SellerWorklet : public mojom::SellerWorklet {
|
||||
// V8State, and avoids having to make a copy of the errors vector.
|
||||
using ScoreAdCallbackInternal = base::OnceCallback<void(
|
||||
double score,
|
||||
mojom::RejectReason reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
absl::optional<uint32_t> scoring_signals_data_version,
|
||||
@ -270,6 +271,7 @@ class CONTENT_EXPORT SellerWorklet : public mojom::SellerWorklet {
|
||||
void PostScoreAdCallbackToUserThread(
|
||||
ScoreAdCallbackInternal callback,
|
||||
double score,
|
||||
mojom::RejectReason reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
absl::optional<uint32_t> scoring_signals_data_version,
|
||||
@ -333,6 +335,7 @@ class CONTENT_EXPORT SellerWorklet : public mojom::SellerWorklet {
|
||||
void DeliverScoreAdCallbackOnUserThread(
|
||||
ScoreAdTaskList::iterator task,
|
||||
double score,
|
||||
mojom::RejectReason reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
absl::optional<uint32_t> scoring_signals_data_version,
|
||||
|
@ -47,7 +47,7 @@ namespace auction_worklet {
|
||||
namespace {
|
||||
|
||||
using PrivateAggregationRequests =
|
||||
std::vector<auction_worklet::mojom::PrivateAggregationRequestPtr>;
|
||||
std::vector<mojom::PrivateAggregationRequestPtr>;
|
||||
|
||||
// Very short time used by some tests that want to wait until just before a
|
||||
// timer triggers.
|
||||
@ -106,16 +106,17 @@ std::string CreateReportToScript(const std::string& raw_return_value,
|
||||
// A ScoreAdClient that takes a callback to call in OnScoreAdComplete().
|
||||
class TestScoreAdClient : public mojom::ScoreAdClient {
|
||||
public:
|
||||
using ScoreAdCompleteCallback = base::OnceCallback<void(
|
||||
double score,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
uint32_t scoring_signals_data_version,
|
||||
bool has_scoring_signals_data_version,
|
||||
const absl::optional<GURL>& debug_loss_report_url,
|
||||
const absl::optional<GURL>& debug_win_report_url,
|
||||
PrivateAggregationRequests pa_requests,
|
||||
const std::vector<std::string>& errors)>;
|
||||
using ScoreAdCompleteCallback =
|
||||
base::OnceCallback<void(double score,
|
||||
mojom::RejectReason reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
uint32_t scoring_signals_data_version,
|
||||
bool has_scoring_signals_data_version,
|
||||
const absl::optional<GURL>& debug_loss_report_url,
|
||||
const absl::optional<GURL>& debug_win_report_url,
|
||||
PrivateAggregationRequests pa_requests,
|
||||
const std::vector<std::string>& errors)>;
|
||||
|
||||
explicit TestScoreAdClient(ScoreAdCompleteCallback score_ad_complete_callback)
|
||||
: score_ad_complete_callback_(std::move(score_ad_complete_callback)) {}
|
||||
@ -133,25 +134,26 @@ class TestScoreAdClient : public mojom::ScoreAdClient {
|
||||
}
|
||||
|
||||
// mojom::ScoreAdClient implementation:
|
||||
void OnScoreAdComplete(
|
||||
double score,
|
||||
auction_worklet::mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
uint32_t scoring_signals_data_version,
|
||||
bool has_scoring_signals_data_version,
|
||||
const absl::optional<GURL>& debug_loss_report_url,
|
||||
const absl::optional<GURL>& debug_win_report_url,
|
||||
PrivateAggregationRequests pa_requests,
|
||||
const std::vector<std::string>& errors) override {
|
||||
void OnScoreAdComplete(double score,
|
||||
mojom::RejectReason reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
uint32_t scoring_signals_data_version,
|
||||
bool has_scoring_signals_data_version,
|
||||
const absl::optional<GURL>& debug_loss_report_url,
|
||||
const absl::optional<GURL>& debug_win_report_url,
|
||||
PrivateAggregationRequests pa_requests,
|
||||
const std::vector<std::string>& errors) override {
|
||||
std::move(score_ad_complete_callback_)
|
||||
.Run(score, std::move(component_auction_modified_bid_params),
|
||||
.Run(score, reject_reason,
|
||||
std::move(component_auction_modified_bid_params),
|
||||
scoring_signals_data_version, has_scoring_signals_data_version,
|
||||
debug_loss_report_url, debug_win_report_url,
|
||||
std::move(pa_requests), errors);
|
||||
}
|
||||
|
||||
static ScoreAdCompleteCallback ScoreAdNeverInvokedCallback() {
|
||||
return base::BindOnce([](double score,
|
||||
return base::BindOnce([](double score, mojom::RejectReason reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
uint32_t scoring_signals_data_version,
|
||||
@ -241,12 +243,15 @@ class SellerWorkletTest : public testing::Test {
|
||||
const absl::optional<GURL>& expected_debug_loss_report_url =
|
||||
absl::nullopt,
|
||||
const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt,
|
||||
mojom::RejectReason expected_reject_reason =
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
PrivateAggregationRequests expected_pa_requests = {}) {
|
||||
RunScoreAdWithJavascriptExpectingResult(
|
||||
CreateScoreAdScript(raw_return_value), expected_score, expected_errors,
|
||||
std::move(expected_component_auction_modified_bid_params),
|
||||
expected_data_version, expected_debug_loss_report_url,
|
||||
expected_debug_win_report_url, std::move(expected_pa_requests));
|
||||
expected_debug_win_report_url, expected_reject_reason,
|
||||
std::move(expected_pa_requests));
|
||||
}
|
||||
|
||||
// Behaves just like RunScoreAdWithReturnValueExpectingResult(), but
|
||||
@ -267,6 +272,8 @@ class SellerWorkletTest : public testing::Test {
|
||||
const absl::optional<GURL>& expected_debug_loss_report_url =
|
||||
absl::nullopt,
|
||||
const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt,
|
||||
mojom::RejectReason expected_reject_reason =
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
PrivateAggregationRequests expected_pa_requests = {}) {
|
||||
AddJavascriptResponse(&url_loader_factory_, decision_logic_url_,
|
||||
CreateScoreAdScript(raw_return_value));
|
||||
@ -277,8 +284,8 @@ class SellerWorkletTest : public testing::Test {
|
||||
seller_worklet.get(), expected_score, expected_errors,
|
||||
std::move(expected_component_auction_modified_bid_params),
|
||||
expected_data_version, expected_debug_loss_report_url,
|
||||
expected_debug_win_report_url, std::move(expected_pa_requests),
|
||||
run_loop.QuitClosure());
|
||||
expected_debug_win_report_url, expected_reject_reason,
|
||||
std::move(expected_pa_requests), run_loop.QuitClosure());
|
||||
task_environment_.FastForwardBy(expected_duration - kTinyTime);
|
||||
EXPECT_FALSE(run_loop.AnyQuitCalled());
|
||||
task_environment_.FastForwardBy(kTinyTime);
|
||||
@ -299,6 +306,8 @@ class SellerWorkletTest : public testing::Test {
|
||||
const absl::optional<GURL>& expected_debug_loss_report_url =
|
||||
absl::nullopt,
|
||||
const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt,
|
||||
mojom::RejectReason expected_reject_reason =
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
PrivateAggregationRequests expected_pa_requests = {}) {
|
||||
SCOPED_TRACE(javascript);
|
||||
AddJavascriptResponse(&url_loader_factory_, decision_logic_url_,
|
||||
@ -307,7 +316,8 @@ class SellerWorkletTest : public testing::Test {
|
||||
expected_score, expected_errors,
|
||||
std::move(expected_component_auction_modified_bid_params),
|
||||
expected_data_version, expected_debug_loss_report_url,
|
||||
expected_debug_win_report_url, std::move(expected_pa_requests));
|
||||
expected_debug_win_report_url, expected_reject_reason,
|
||||
std::move(expected_pa_requests));
|
||||
}
|
||||
|
||||
// Runs score_ad() script, checking result and invoking provided closure
|
||||
@ -321,6 +331,7 @@ class SellerWorkletTest : public testing::Test {
|
||||
absl::optional<uint32_t> expected_data_version,
|
||||
const absl::optional<GURL>& expected_debug_loss_report_url,
|
||||
const absl::optional<GURL>& expected_debug_win_report_url,
|
||||
mojom::RejectReason expected_reject_reason,
|
||||
PrivateAggregationRequests expected_pa_requests,
|
||||
base::OnceClosure done_closure) {
|
||||
seller_worklet->ScoreAd(
|
||||
@ -332,6 +343,7 @@ class SellerWorkletTest : public testing::Test {
|
||||
/*trace_id=*/1,
|
||||
TestScoreAdClient::Create(base::BindOnce(
|
||||
[](double expected_score,
|
||||
mojom::RejectReason expected_reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
expected_component_auction_modified_bid_params,
|
||||
absl::optional<uint32_t> expected_data_version,
|
||||
@ -340,6 +352,7 @@ class SellerWorkletTest : public testing::Test {
|
||||
PrivateAggregationRequests expected_pa_requests,
|
||||
std::vector<std::string> expected_errors,
|
||||
base::OnceClosure done_closure, double score,
|
||||
mojom::RejectReason reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
uint32_t data_version, bool has_data_version,
|
||||
@ -351,6 +364,8 @@ class SellerWorkletTest : public testing::Test {
|
||||
if (has_data_version)
|
||||
maybe_data_version = data_version;
|
||||
EXPECT_EQ(expected_score, score);
|
||||
EXPECT_EQ(static_cast<int>(expected_reject_reason),
|
||||
static_cast<int>(reject_reason));
|
||||
EXPECT_EQ(
|
||||
expected_component_auction_modified_bid_params.is_null(),
|
||||
component_auction_modified_bid_params.is_null());
|
||||
@ -373,7 +388,7 @@ class SellerWorkletTest : public testing::Test {
|
||||
EXPECT_EQ(expected_errors, errors);
|
||||
std::move(done_closure).Run();
|
||||
},
|
||||
expected_score,
|
||||
expected_score, expected_reject_reason,
|
||||
std::move(expected_component_auction_modified_bid_params),
|
||||
expected_data_version, expected_debug_loss_report_url,
|
||||
expected_debug_win_report_url, std::move(expected_pa_requests),
|
||||
@ -406,14 +421,16 @@ class SellerWorkletTest : public testing::Test {
|
||||
const absl::optional<GURL>& expected_debug_loss_report_url =
|
||||
absl::nullopt,
|
||||
const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt,
|
||||
mojom::RejectReason expected_reject_reason =
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
PrivateAggregationRequests expected_pa_requests = {}) {
|
||||
base::RunLoop run_loop;
|
||||
RunScoreAdOnWorkletAsync(
|
||||
seller_worklet, expected_score, expected_errors,
|
||||
std::move(expected_component_auction_modified_bid_params),
|
||||
expected_data_version, expected_debug_loss_report_url,
|
||||
expected_debug_win_report_url, std::move(expected_pa_requests),
|
||||
run_loop.QuitClosure());
|
||||
expected_debug_win_report_url, expected_reject_reason,
|
||||
std::move(expected_pa_requests), run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
@ -429,6 +446,8 @@ class SellerWorkletTest : public testing::Test {
|
||||
const absl::optional<GURL>& expected_debug_loss_report_url =
|
||||
absl::nullopt,
|
||||
const absl::optional<GURL>& expected_debug_win_report_url = absl::nullopt,
|
||||
mojom::RejectReason expected_reject_reason =
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
PrivateAggregationRequests expected_pa_requests = {}) {
|
||||
auto seller_worklet = CreateWorklet();
|
||||
ASSERT_TRUE(seller_worklet);
|
||||
@ -436,7 +455,8 @@ class SellerWorkletTest : public testing::Test {
|
||||
seller_worklet.get(), expected_score, expected_errors,
|
||||
std::move(expected_component_auction_modified_bid_params),
|
||||
expected_data_version, expected_debug_loss_report_url,
|
||||
expected_debug_win_report_url, std::move(expected_pa_requests));
|
||||
expected_debug_win_report_url, expected_reject_reason,
|
||||
std::move(expected_pa_requests));
|
||||
}
|
||||
|
||||
// Configures `url_loader_factory_` to return a report_result() script created
|
||||
@ -658,7 +678,7 @@ class SellerWorkletTest : public testing::Test {
|
||||
uint32_t browser_signal_bidding_duration_msecs_;
|
||||
double browser_signal_desireability_;
|
||||
double browser_signal_highest_scoring_other_bid_;
|
||||
auction_worklet::mojom::ComponentAuctionReportResultParamsPtr
|
||||
mojom::ComponentAuctionReportResultParamsPtr
|
||||
browser_signals_component_auction_report_result_params_;
|
||||
absl::optional<uint32_t> browser_signal_data_version_;
|
||||
absl::optional<base::TimeDelta> seller_timeout_;
|
||||
@ -901,6 +921,80 @@ TEST_F(SellerWorkletTest, ScoreAdAd) {
|
||||
/*ad=*/"[[35]]", /*bid=*/0, /*has_bid=*/false));
|
||||
}
|
||||
|
||||
// Test the `rejectReason` output field of scoreAd().
|
||||
TEST_F(SellerWorkletTest, ScoreAdRejectReason) {
|
||||
const struct {
|
||||
std::string reason_str;
|
||||
mojom::RejectReason reason_enum;
|
||||
} kTestCases[] = {
|
||||
{"not-available", mojom::RejectReason::kNotAvailable},
|
||||
{"invalid-bid", mojom::RejectReason::kInvalidBid},
|
||||
{"bid-below-auction-floor", mojom::RejectReason::kBidBelowAuctionFloor},
|
||||
{"pending-approval-by-exchange",
|
||||
mojom::RejectReason::kPendingApprovalByExchange},
|
||||
{"disapproved-by-exchange", mojom::RejectReason::kDisapprovedByExchange},
|
||||
{"blocked-by-publisher", mojom::RejectReason::kBlockedByPublisher},
|
||||
{"language-exclusions", mojom::RejectReason::kLanguageExclusions},
|
||||
{"category-exclusions", mojom::RejectReason::kCategoryExclusions},
|
||||
};
|
||||
|
||||
for (const auto& test_case : kTestCases) {
|
||||
RunScoreAdWithReturnValueExpectingResult(
|
||||
base::StringPrintf(R"({desirability:-1, rejectReason: '%s'})",
|
||||
test_case.reason_str.c_str()),
|
||||
0,
|
||||
/*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt, test_case.reason_enum);
|
||||
}
|
||||
|
||||
// Default reject reason is mojom::RejectReason::kNotAvailable, if scoreAd()
|
||||
// does not return one.
|
||||
RunScoreAdWithReturnValueExpectingResult(
|
||||
"{desirability:-1}", 0,
|
||||
/*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
mojom::RejectReason::kNotAvailable);
|
||||
|
||||
// Reject reason is ignored when desirability is positive.
|
||||
RunScoreAdWithReturnValueExpectingResult(
|
||||
"{desirability:3, rejectReason: 'invalid-bid'}", 3,
|
||||
/*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason*/ mojom::RejectReason::kNotAvailable);
|
||||
}
|
||||
|
||||
// Invalid `rejectReason` output of scoreAd() results in error.
|
||||
TEST_F(SellerWorkletTest, ScoreAdInvalidRejectReason) {
|
||||
// Reject reason string returned by seller script is case sensitive.
|
||||
RunScoreAdWithReturnValueExpectingResult(
|
||||
"{desirability:-1, rejectReason: 'INVALID-BID'}", 0,
|
||||
/*expected_errors=*/
|
||||
{"https://url.test/ scoreAd() returned an invalid reject reason."},
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason*/ mojom::RejectReason::kNotAvailable);
|
||||
|
||||
// Reject reason returned by seller script must be a string.
|
||||
RunScoreAdWithReturnValueExpectingResult(
|
||||
"{desirability:-1, rejectReason: 2}", 0,
|
||||
/*expected_errors=*/
|
||||
{"https://url.test/ rejectReason returned by scoreAd() must be a "
|
||||
"string."},
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason*/ mojom::RejectReason::kNotAvailable);
|
||||
}
|
||||
|
||||
// Test the `bid` output field of scoreAd().
|
||||
TEST_F(SellerWorkletTest, ScoreAdModifiesBid) {
|
||||
// When `browser_signals_other_seller_` is not top a top-level auction (i.e.
|
||||
@ -1296,6 +1390,8 @@ TEST_F(SellerWorkletTest, ScoreAdParallelBeforeLoadComplete) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{},
|
||||
base::BindLambdaForTesting([&]() {
|
||||
++num_completed_worklets;
|
||||
@ -1338,6 +1434,8 @@ TEST_F(SellerWorkletTest, ScoreAdParallelAfterLoadComplete) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{},
|
||||
base::BindLambdaForTesting([&]() {
|
||||
++num_completed_worklets;
|
||||
@ -1402,6 +1500,8 @@ TEST_F(SellerWorkletTest, ScoreAdParallelTrustedScoringSignalsNotBatched) {
|
||||
/*expected_data_version=*/i,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{},
|
||||
base::BindLambdaForTesting([&]() {
|
||||
++num_completed_worklets;
|
||||
@ -1469,6 +1569,8 @@ TEST_F(SellerWorkletTest, ScoreAdParallelTrustedScoringSignalsBatched1) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{},
|
||||
base::BindLambdaForTesting([&]() {
|
||||
++num_completed_worklets;
|
||||
@ -1527,6 +1629,8 @@ TEST_F(SellerWorkletTest, ScoreAdParallelTrustedScoringSignalsBatched2) {
|
||||
/*expected_data_version=*/10,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{},
|
||||
base::BindLambdaForTesting([&]() {
|
||||
++num_completed_worklets;
|
||||
@ -1594,6 +1698,8 @@ TEST_F(SellerWorkletTest, ScoreAdParallelTrustedScoringSignalsBatched3) {
|
||||
/*expected_data_version=*/10,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{},
|
||||
base::BindLambdaForTesting([&]() {
|
||||
++num_completed_worklets;
|
||||
@ -1849,7 +1955,7 @@ TEST_F(SellerWorkletTest, ReportResultTopLevelSeller) {
|
||||
mojom::ComponentAuctionOtherSeller::NewTopLevelSeller(
|
||||
url::Origin::Create(GURL("https://top.seller.test")));
|
||||
browser_signals_component_auction_report_result_params_ =
|
||||
auction_worklet::mojom::ComponentAuctionReportResultParams::New(
|
||||
mojom::ComponentAuctionReportResultParams::New(
|
||||
/*top_level_seller_signals=*/"null",
|
||||
/*modified_bid=*/0,
|
||||
/*has_modified_bid=*/false);
|
||||
@ -1879,7 +1985,7 @@ TEST_F(SellerWorkletTest, ReportResultComponentSeller) {
|
||||
mojom::ComponentAuctionOtherSeller::NewTopLevelSeller(
|
||||
url::Origin::Create(GURL("https://top.seller.test")));
|
||||
browser_signals_component_auction_report_result_params_ =
|
||||
auction_worklet::mojom::ComponentAuctionReportResultParams::New(
|
||||
mojom::ComponentAuctionReportResultParams::New(
|
||||
/*top_level_seller_signals=*/"null",
|
||||
/*modified_bid=*/0,
|
||||
/*has_modified_bid=*/false);
|
||||
@ -1923,7 +2029,7 @@ TEST_F(SellerWorkletTest, ReportResultTopLevelSellerSignals) {
|
||||
mojom::ComponentAuctionOtherSeller::NewTopLevelSeller(
|
||||
url::Origin::Create(GURL("https://top.seller.test")));
|
||||
browser_signals_component_auction_report_result_params_ =
|
||||
auction_worklet::mojom::ComponentAuctionReportResultParams::New(
|
||||
mojom::ComponentAuctionReportResultParams::New(
|
||||
/*top_level_seller_signals=*/"null",
|
||||
/*modified_bid=*/0,
|
||||
/*has_modified_bid=*/false);
|
||||
@ -1965,7 +2071,7 @@ TEST_F(SellerWorkletTest, ReportResultModifiedBid) {
|
||||
mojom::ComponentAuctionOtherSeller::NewTopLevelSeller(
|
||||
url::Origin::Create(GURL("https://top.seller.test")));
|
||||
browser_signals_component_auction_report_result_params_ =
|
||||
auction_worklet::mojom::ComponentAuctionReportResultParams::New(
|
||||
mojom::ComponentAuctionReportResultParams::New(
|
||||
/*top_level_seller_signals=*/"null",
|
||||
/*modified_bid=*/4,
|
||||
/*has_modified_bid=*/true);
|
||||
@ -2365,7 +2471,7 @@ TEST_F(SellerWorkletTest, ScriptIsolation) {
|
||||
seller_timeout_,
|
||||
/*trace_id=*/1,
|
||||
TestScoreAdClient::Create(base::BindLambdaForTesting(
|
||||
[&run_loop](double score,
|
||||
[&run_loop](double score, mojom::RejectReason reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
uint32_t scoring_signals_data_version,
|
||||
@ -2483,6 +2589,8 @@ TEST_F(SellerWorkletTest, PauseOnStart) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{}, run_loop.QuitClosure());
|
||||
|
||||
// Give it a chance to fetch.
|
||||
@ -2565,6 +2673,8 @@ TEST_F(SellerWorkletTest, BasicV8Debug) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{}, run_loop1.QuitClosure());
|
||||
|
||||
decision_logic_url_ = kUrl2;
|
||||
@ -2578,6 +2688,8 @@ TEST_F(SellerWorkletTest, BasicV8Debug) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{}, run_loop2.QuitClosure());
|
||||
|
||||
int id1 = worklet_impl1->context_group_id_for_testing();
|
||||
@ -2693,22 +2805,27 @@ TEST_F(SellerWorkletTest, BasicDevToolsDebug) {
|
||||
auto worklet1 = CreateWorklet(/*pause_for_debugger_on_start=*/true);
|
||||
base::RunLoop run_loop1;
|
||||
RunScoreAdOnWorkletAsync(
|
||||
worklet1.get(), 100.5, {}, mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
worklet1.get(), /*expected_score=*/100.5, /*expected_errors=*/{},
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{}, run_loop1.QuitClosure());
|
||||
|
||||
decision_logic_url_ = GURL(kUrl2);
|
||||
auto worklet2 = CreateWorklet(/*pause_for_debugger_on_start=*/true);
|
||||
base::RunLoop run_loop2;
|
||||
RunScoreAdOnWorkletAsync(worklet2.get(), 0,
|
||||
RunScoreAdOnWorkletAsync(worklet2.get(), /*expected_score=*/0,
|
||||
{"http://example.org/second.js scoreAd() did not "
|
||||
"return an object or a number."},
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{},
|
||||
run_loop2.QuitClosure());
|
||||
|
||||
@ -2848,11 +2965,14 @@ TEST_F(SellerWorkletTest, InstrumentationBreakpoints) {
|
||||
decision_logic_url_ = GURL(kUrl);
|
||||
auto worklet = CreateWorklet(/*pause_for_debugger_on_start=*/true);
|
||||
base::RunLoop run_loop;
|
||||
RunScoreAdOnWorkletAsync(worklet.get(), 1.0, {},
|
||||
RunScoreAdOnWorkletAsync(worklet.get(), /*expected_score=*/1.0,
|
||||
/*expected_errors=*/{},
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{}, run_loop.QuitClosure());
|
||||
|
||||
mojo::AssociatedRemote<blink::mojom::DevToolsAgent> agent;
|
||||
@ -2926,10 +3046,13 @@ TEST_F(SellerWorkletTest, InstrumentationBreakpoints) {
|
||||
// remove it.
|
||||
base::RunLoop run_loop3;
|
||||
RunScoreAdOnWorkletAsync(
|
||||
worklet.get(), 1.0, {}, mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
worklet.get(), /*expected_score=*/1.0, /*expected_errors=*/{},
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{}, run_loop3.QuitClosure());
|
||||
|
||||
TestDevToolsAgentClient::Event breakpoint_hit3 =
|
||||
@ -2988,10 +3111,13 @@ TEST_F(SellerWorkletTest, UnloadWhilePaused) {
|
||||
R"({"id":4,"method":"Runtime.runIfWaitingForDebugger","params":{}})");
|
||||
|
||||
RunScoreAdOnWorkletAsync(
|
||||
worklet.get(), 1.0, {}, mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
worklet.get(), /*expected_score=*/1.0, /*expected_errors=*/{},
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/
|
||||
mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{}, base::BindOnce([]() {
|
||||
ADD_FAILURE() << "scoreAd shouldn't actually get to finish.";
|
||||
}));
|
||||
@ -3399,7 +3525,7 @@ TEST_F(SellerWorkletBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
seller_timeout_,
|
||||
/*trace_id=*/1,
|
||||
TestScoreAdClient::Create(base::BindLambdaForTesting(
|
||||
[&run_loop](double score,
|
||||
[&run_loop](double score, mojom::RejectReason reject_reason,
|
||||
mojom::ComponentAuctionModifiedBidParamsPtr
|
||||
component_auction_modified_bid_params,
|
||||
uint32_t scoring_signals_data_version,
|
||||
@ -3436,15 +3562,15 @@ class SellerWorkletPrivateAggregationEnabledTest : public SellerWorkletTest {
|
||||
};
|
||||
|
||||
TEST_F(SellerWorkletPrivateAggregationEnabledTest, ScoreAd) {
|
||||
auction_worklet::mojom::PrivateAggregationRequestPtr kExpectedRequest1 =
|
||||
auction_worklet::mojom::PrivateAggregationRequest::New(
|
||||
mojom::PrivateAggregationRequestPtr kExpectedRequest1 =
|
||||
mojom::PrivateAggregationRequest::New(
|
||||
content::mojom::AggregatableReportHistogramContribution::New(
|
||||
/*bucket=*/123,
|
||||
/*value=*/45),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New());
|
||||
auction_worklet::mojom::PrivateAggregationRequestPtr kExpectedRequest2 =
|
||||
auction_worklet::mojom::PrivateAggregationRequest::New(
|
||||
mojom::PrivateAggregationRequestPtr kExpectedRequest2 =
|
||||
mojom::PrivateAggregationRequest::New(
|
||||
content::mojom::AggregatableReportHistogramContribution::New(
|
||||
/*bucket=*/absl::MakeInt128(/*high=*/1, /*low=*/0),
|
||||
/*value=*/1),
|
||||
@ -3464,6 +3590,7 @@ TEST_F(SellerWorkletPrivateAggregationEnabledTest, ScoreAd) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/mojom::RejectReason::kNotAvailable,
|
||||
std::move(expected_pa_requests));
|
||||
}
|
||||
|
||||
@ -3481,6 +3608,7 @@ TEST_F(SellerWorkletPrivateAggregationEnabledTest, ScoreAd) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/mojom::RejectReason::kNotAvailable,
|
||||
std::move(expected_pa_requests));
|
||||
}
|
||||
|
||||
@ -3498,6 +3626,7 @@ TEST_F(SellerWorkletPrivateAggregationEnabledTest, ScoreAd) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/mojom::RejectReason::kNotAvailable,
|
||||
std::move(expected_pa_requests));
|
||||
}
|
||||
|
||||
@ -3518,6 +3647,7 @@ TEST_F(SellerWorkletPrivateAggregationEnabledTest, ScoreAd) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/mojom::RejectReason::kNotAvailable,
|
||||
std::move(expected_pa_requests));
|
||||
}
|
||||
|
||||
@ -3537,18 +3667,18 @@ TEST_F(SellerWorkletPrivateAggregationEnabledTest, ScoreAd) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/mojom::RejectReason::kNotAvailable,
|
||||
std::move(expected_pa_requests));
|
||||
}
|
||||
|
||||
// Debug mode enabled with debug key
|
||||
{
|
||||
PrivateAggregationRequests expected_pa_requests;
|
||||
expected_pa_requests.push_back(
|
||||
auction_worklet::mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest1->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, content::mojom::DebugKey::New(1234u))));
|
||||
expected_pa_requests.push_back(mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest1->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, content::mojom::DebugKey::New(1234u))));
|
||||
|
||||
RunScoreAdWithJavascriptExpectingResult(
|
||||
CreateScoreAdScript("5",
|
||||
@ -3561,24 +3691,23 @@ TEST_F(SellerWorkletPrivateAggregationEnabledTest, ScoreAd) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/mojom::RejectReason::kNotAvailable,
|
||||
std::move(expected_pa_requests));
|
||||
}
|
||||
|
||||
// Debug mode enabled without debug key, but with multiple requests
|
||||
{
|
||||
PrivateAggregationRequests expected_pa_requests;
|
||||
expected_pa_requests.push_back(
|
||||
auction_worklet::mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest1->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, /*debug_key=*/nullptr)));
|
||||
expected_pa_requests.push_back(
|
||||
auction_worklet::mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest2->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, /*debug_key=*/nullptr)));
|
||||
expected_pa_requests.push_back(mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest1->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, /*debug_key=*/nullptr)));
|
||||
expected_pa_requests.push_back(mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest2->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, /*debug_key=*/nullptr)));
|
||||
|
||||
RunScoreAdWithJavascriptExpectingResult(
|
||||
CreateScoreAdScript("5",
|
||||
@ -3593,20 +3722,21 @@ TEST_F(SellerWorkletPrivateAggregationEnabledTest, ScoreAd) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/mojom::RejectReason::kNotAvailable,
|
||||
std::move(expected_pa_requests));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SellerWorkletPrivateAggregationEnabledTest, ReportResult) {
|
||||
auction_worklet::mojom::PrivateAggregationRequestPtr kExpectedRequest1 =
|
||||
auction_worklet::mojom::PrivateAggregationRequest::New(
|
||||
mojom::PrivateAggregationRequestPtr kExpectedRequest1 =
|
||||
mojom::PrivateAggregationRequest::New(
|
||||
content::mojom::AggregatableReportHistogramContribution::New(
|
||||
/*bucket=*/123,
|
||||
/*value=*/45),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New());
|
||||
auction_worklet::mojom::PrivateAggregationRequestPtr kExpectedRequest2 =
|
||||
auction_worklet::mojom::PrivateAggregationRequest::New(
|
||||
mojom::PrivateAggregationRequestPtr kExpectedRequest2 =
|
||||
mojom::PrivateAggregationRequest::New(
|
||||
content::mojom::AggregatableReportHistogramContribution::New(
|
||||
/*bucket=*/absl::MakeInt128(/*high=*/1, /*low=*/0),
|
||||
/*value=*/1),
|
||||
@ -3696,12 +3826,11 @@ TEST_F(SellerWorkletPrivateAggregationEnabledTest, ReportResult) {
|
||||
// Debug mode enabled with debug key
|
||||
{
|
||||
PrivateAggregationRequests expected_pa_requests;
|
||||
expected_pa_requests.push_back(
|
||||
auction_worklet::mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest1->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, content::mojom::DebugKey::New(1234u))));
|
||||
expected_pa_requests.push_back(mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest1->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, content::mojom::DebugKey::New(1234u))));
|
||||
|
||||
RunReportResultCreatedScriptExpectingResult(
|
||||
"5",
|
||||
@ -3718,18 +3847,16 @@ TEST_F(SellerWorkletPrivateAggregationEnabledTest, ReportResult) {
|
||||
// Debug mode enabled without debug key, but with multiple requests
|
||||
{
|
||||
PrivateAggregationRequests expected_pa_requests;
|
||||
expected_pa_requests.push_back(
|
||||
auction_worklet::mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest1->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, /*debug_key=*/nullptr)));
|
||||
expected_pa_requests.push_back(
|
||||
auction_worklet::mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest2->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, /*debug_key=*/nullptr)));
|
||||
expected_pa_requests.push_back(mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest1->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, /*debug_key=*/nullptr)));
|
||||
expected_pa_requests.push_back(mojom::PrivateAggregationRequest::New(
|
||||
kExpectedRequest2->contribution->Clone(),
|
||||
content::mojom::AggregationServiceMode::kDefault,
|
||||
content::mojom::DebugModeDetails::New(
|
||||
/*is_enabled=*/true, /*debug_key=*/nullptr)));
|
||||
|
||||
RunReportResultCreatedScriptExpectingResult(
|
||||
"5",
|
||||
@ -3784,6 +3911,7 @@ TEST_F(SellerWorkletPrivateAggregationDisabledTest, ScoreAd) {
|
||||
/*expected_data_version=*/absl::nullopt,
|
||||
/*expected_debug_loss_report_url=*/absl::nullopt,
|
||||
/*expected_debug_win_report_url=*/absl::nullopt,
|
||||
/*expected_reject_reason=*/mojom::RejectReason::kNotAvailable,
|
||||
/*expected_pa_requests=*/{});
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user