[FLEDGE] Add some basic component auction WPT tests.
In particular, test:
* allowComponentAuction
* Top-level auctions can't have buyers.
* Auction worklet origin parameters.
* Bid passing/modification.
Bug: 1425952
Change-Id: Iccc59be915332ab38f85fd84e5ce9f290ece184e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5008033
Commit-Queue: Matt Menke <mmenke@chromium.org>
Reviewed-by: Maks Orlovich <morlovich@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1220413}
diff --git a/fledge/tentative/component-auction.https.window.js b/fledge/tentative/component-auction.https.window.js
new file mode 100644
index 0000000..cfaf174
--- /dev/null
+++ b/fledge/tentative/component-auction.https.window.js
@@ -0,0 +1,437 @@
+// META: script=/resources/testdriver.js
+// META: script=/common/utils.js
+// META: script=/common/subset-tests.js
+// META: script=resources/fledge-util.sub.js
+// META: timeout=long
+// META: variant=?1-5
+// META: variant=?6-10
+// META: variant=?11-last
+
+"use strict";
+
+// Creates an AuctionConfig with a single component auction.
+function createComponentAuctionConfig(uuid) {
+ let componentAuctionConfig = {
+ seller: window.location.origin,
+ decisionLogicURL: createDecisionScriptURL(uuid),
+ interestGroupBuyers: [window.location.origin]
+ };
+
+ return {
+ seller: window.location.origin,
+ decisionLogicURL: createDecisionScriptURL(uuid),
+ interestGroupBuyers: [],
+ componentAuctions: [componentAuctionConfig]
+ };
+}
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ await joinInterestGroup(
+ test, uuid,
+ { biddingLogicURL: createBiddingScriptURL()});
+
+ await runBasicFledgeTestExpectingNoWinner(test, uuid, createComponentAuctionConfig(uuid));
+}, 'Component auction allowed not specified by bidder.');
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ await joinInterestGroup(
+ test, uuid,
+ { biddingLogicURL: createBiddingScriptURL(
+ { allowComponentAuction: false })});
+
+ await runBasicFledgeTestExpectingNoWinner(test, uuid, createComponentAuctionConfig(uuid));
+}, 'Component auction not allowed by bidder.');
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ await joinInterestGroup(
+ test, uuid,
+ { biddingLogicURL: createBiddingScriptURL(
+ { allowComponentAuction: true })});
+
+ let auctionConfig = createComponentAuctionConfig(uuid);
+ auctionConfig.componentAuctions[0].decisionLogicURL = createDecisionScriptURL(
+ uuid,
+ { scoreAd: "return 5;" });
+
+ await runBasicFledgeTestExpectingNoWinner(test, uuid, auctionConfig);
+}, 'Component auction allowed not specified by component seller.');
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ await joinInterestGroup(
+ test, uuid,
+ { biddingLogicURL: createBiddingScriptURL(
+ { allowComponentAuction: true })});
+
+ let auctionConfig = createComponentAuctionConfig(uuid);
+ auctionConfig.componentAuctions[0].decisionLogicURL = createDecisionScriptURL(
+ uuid,
+ { scoreAd: "return {desirability: 5, allowComponentAuction: false};" });
+
+ await runBasicFledgeTestExpectingNoWinner(test, uuid, auctionConfig);
+}, 'Component auction not allowed by component seller.');
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ await joinInterestGroup(
+ test, uuid,
+ { biddingLogicURL: createBiddingScriptURL(
+ { allowComponentAuction: true })});
+
+ let auctionConfig = createComponentAuctionConfig(uuid);
+ auctionConfig.decisionLogicURL = createDecisionScriptURL(
+ uuid,
+ { scoreAd: "return 5;" });
+
+ await runBasicFledgeTestExpectingNoWinner(test, uuid, auctionConfig);
+}, 'Component auction allowed not specified by top-level seller.');
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ await joinInterestGroup(
+ test, uuid,
+ { biddingLogicURL: createBiddingScriptURL(
+ { allowComponentAuction: true })});
+
+ let auctionConfig = createComponentAuctionConfig(uuid);
+ auctionConfig.interestGroupBuyers = [window.location.origin];
+
+ try {
+ await runBasicFledgeAuction(test, uuid, auctionConfig);
+ } catch (exception) {
+ assert_true(exception instanceof TypeError, "did not get expected error: " + exception);
+ return;
+ }
+ throw 'Exception unexpectedly not thrown.'
+}, 'Component auction top-level auction cannot have buyers.');
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ await joinInterestGroup(
+ test, uuid,
+ { biddingLogicURL: createBiddingScriptURL(
+ { allowComponentAuction: true })});
+
+ let auctionConfig = createComponentAuctionConfig(uuid);
+ auctionConfig.decisionLogicURL = createDecisionScriptURL(
+ uuid,
+ { scoreAd: "return {desirability: 5, allowComponentAuction: false};" });
+
+ await runBasicFledgeTestExpectingNoWinner(test, uuid, auctionConfig);
+}, 'Component auction not allowed by top-level seller.');
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ // Use distinct origins so can validate all origin parameters passed to worklets.
+ let bidder = OTHER_ORIGIN1;
+ let componentSeller = OTHER_ORIGIN2;
+ let topLevelSeller = OTHER_ORIGIN3;
+
+ let bidderReportURL = createBidderReportURL(uuid);
+ let componentSellerReportURL = createSellerReportURL(uuid, /*id=*/1);
+ let topLevelSellerReportURL = createSellerReportURL(uuid, /*id=*/2);
+
+ // Note that generateBid() and reportWin() receive slightly different
+ // "browserSignals" fields - only reportWin() gets "interestGroupOwner", so
+ // need different sets of checks for them.
+ await joinCrossOriginInterestGroup(
+ test, uuid, bidder,
+ { biddingLogicURL: createBiddingScriptURL(
+ { origin: bidder,
+ allowComponentAuction: true,
+ generateBid:
+ `if (browserSignals.seller !== "${componentSeller}")
+ throw "Unexpected seller: " + browserSignals.seller;
+ if (browserSignals.componentSeller !== undefined)
+ throw "Unexpected componentSeller: " + browserSignals.componentSeller;
+ if (browserSignals.topLevelSeller !== "${topLevelSeller}")
+ throw "Unexpected topLevelSeller: " + browserSignals.topLevelSeller;
+ if (browserSignals.interestGroupOwner !== undefined)
+ throw "Unexpected interestGroupOwner: " + browserSignals.interestGroupOwner;
+ if (browserSignals.topWindowHostname !== "${window.location.hostname}")
+ throw "Unexpected topWindowHostname: " + browserSignals.topWindowHostname;`,
+ reportWin:
+ `if (browserSignals.seller !== "${componentSeller}")
+ throw "Unexpected seller: " + browserSignals.seller;
+ if (browserSignals.componentSeller !== undefined)
+ throw "Unexpected componentSeller: " + browserSignals.componentSeller;
+ if (browserSignals.topLevelSeller !== "${topLevelSeller}")
+ throw "Unexpected topLevelSeller: " + browserSignals.topLevelSeller;
+ if (browserSignals.interestGroupOwner !== "${bidder}")
+ throw "Unexpected interestGroupOwner: " + browserSignals.interestGroupOwner;
+ if (browserSignals.topWindowHostname !== "${window.location.hostname}")
+ throw "Unexpected topWindowHostname: " + browserSignals.topWindowHostname;
+ sendReportTo("${bidderReportURL}");`})});
+
+ // Checks for scoreAd() and reportResult() for the component seller.
+ let componentSellerChecks =
+ `if (browserSignals.seller !== undefined)
+ throw "Unexpected seller: " + browserSignals.seller;
+ if (browserSignals.componentSeller !== undefined)
+ throw "Unexpected componentSeller: " + browserSignals.componentSeller;
+ if (browserSignals.topLevelSeller !== "${topLevelSeller}")
+ throw "Unexpected topLevelSeller: " + browserSignals.topLevelSeller;
+ if (browserSignals.interestGroupOwner !== "${bidder}")
+ throw "Unexpected interestGroupOwner: " + browserSignals.interestGroupOwner;
+ if (browserSignals.topWindowHostname !== "${window.location.hostname}")
+ throw "Unexpected topWindowHostname: " + browserSignals.topWindowHostname;`;
+
+ let componentAuctionConfig = {
+ seller: componentSeller,
+ decisionLogicURL: createDecisionScriptURL(
+ uuid,
+ { origin: componentSeller,
+ scoreAd: componentSellerChecks,
+ reportResult: `${componentSellerChecks}
+ sendReportTo("${componentSellerReportURL}");` }),
+ interestGroupBuyers: [bidder]
+ };
+
+ // Checks for scoreAd() and reportResult() for the top-level seller.
+ let topLevelSellerChecks =
+ `if (browserSignals.seller !== undefined)
+ throw "Unexpected seller: " + browserSignals.seller;
+ if (browserSignals.componentSeller !== "${componentSeller}")
+ throw "Unexpected componentSeller: " + browserSignals.componentSeller;
+ if (browserSignals.topLevelSeller !== undefined)
+ throw "Unexpected topLevelSeller: " + browserSignals.topLevelSeller;
+ if (browserSignals.interestGroupOwner !== "${bidder}")
+ throw "Unexpected interestGroupOwner: " + browserSignals.interestGroupOwner;
+ if (browserSignals.topWindowHostname !== "${window.location.hostname}")
+ throw "Unexpected topWindowHostname: " + browserSignals.topWindowHostname;`;
+
+ let auctionConfigOverrides = {
+ seller: topLevelSeller,
+ decisionLogicURL: createDecisionScriptURL(
+ uuid,
+ { origin: topLevelSeller,
+ scoreAd: topLevelSellerChecks,
+ reportResult: `${topLevelSellerChecks}
+ sendReportTo("${topLevelSellerReportURL}");` }),
+ interestGroupBuyers: [],
+ componentAuctions: [componentAuctionConfig]
+ };
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfigOverrides);
+ await waitForObservedRequests(
+ uuid,
+ [bidderReportURL, componentSellerReportURL, topLevelSellerReportURL]);
+}, 'Component auction browserSignals origins.');
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ let bidderReportURL = createBidderReportURL(uuid);
+ let componentSellerReportURL = createSellerReportURL(uuid, /*id=*/1);
+ let topLevelSellerReportURL = createSellerReportURL(uuid, /*id=*/2);
+
+ await joinInterestGroup(
+ test, uuid,
+ { biddingLogicURL: createBiddingScriptURL(
+ { allowComponentAuction: true,
+ bid: 5,
+ reportWin:
+ `if (browserSignals.bid !== 5)
+ throw "Unexpected bid: " + browserSignals.bid;
+ sendReportTo("${bidderReportURL}");`})});
+
+ let auctionConfig = createComponentAuctionConfig(uuid);
+
+ auctionConfig.componentAuctions[0].decisionLogicURL =
+ createDecisionScriptURL(
+ uuid,
+ { scoreAd:
+ `if (bid !== 5)
+ throw "Unexpected component bid: " + bid`,
+ reportResult:
+ `if (browserSignals.bid !== 5)
+ throw "Unexpected component browserSignals.bid: " + browserSignals.bid;
+ if (browserSignals.modifiedBid !== undefined)
+ throw "Unexpected component browserSignals.modifiedBid: " + browserSignals.modifiedBid;
+ sendReportTo("${componentSellerReportURL}");` });
+
+ auctionConfig.decisionLogicURL =
+ createDecisionScriptURL(
+ uuid,
+ { scoreAd:
+ `if (bid !== 5)
+ throw "Unexpected top-level bid: " + bid`,
+ reportResult:
+ `if (browserSignals.bid !== 5)
+ throw "Unexpected top-level browserSignals.bid: " + browserSignals.bid;
+ if (browserSignals.modifiedBid !== undefined)
+ throw "Unexpected top-level browserSignals.modifiedBid: " + browserSignals.modifiedBid;
+ sendReportTo("${topLevelSellerReportURL}");` });
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfig);
+ await waitForObservedRequests(
+ uuid,
+ [bidderReportURL, componentSellerReportURL, topLevelSellerReportURL]);
+}, 'Component auction unmodified bid.');
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ let bidderReportURL = createBidderReportURL(uuid);
+ let componentSellerReportURL = createSellerReportURL(uuid, /*id=*/1);
+ let topLevelSellerReportURL = createSellerReportURL(uuid, /*id=*/2);
+
+ await joinInterestGroup(
+ test, uuid,
+ { biddingLogicURL: createBiddingScriptURL(
+ { allowComponentAuction: true,
+ bid: 5,
+ reportWin:
+ `if (browserSignals.bid !== 5)
+ throw "Unexpected bid: " + browserSignals.bid;
+ sendReportTo("${bidderReportURL}");`})});
+
+ let auctionConfig = createComponentAuctionConfig(uuid);
+
+ auctionConfig.componentAuctions[0].decisionLogicURL =
+ createDecisionScriptURL(
+ uuid,
+ { scoreAd:
+ `if (bid !== 5)
+ throw "Unexpected component bid: " + bid
+ return {desirability: 5, allowComponentAuction: true, bid: 4};`,
+ reportResult:
+ `if (browserSignals.bid !== 5)
+ throw "Unexpected component browserSignals.bid: " + browserSignals.bid;
+ if (browserSignals.modifiedBid !== 4)
+ throw "Unexpected component browserSignals.modifiedBid: " + browserSignals.modifiedBid;
+ sendReportTo("${componentSellerReportURL}");` });
+
+ auctionConfig.decisionLogicURL =
+ createDecisionScriptURL(
+ uuid,
+ { scoreAd:
+ `if (bid !== 4)
+ throw "Unexpected top-level bid: " + bid`,
+ reportResult:
+ `if (browserSignals.bid !== 4)
+ throw "Unexpected top-level browserSignals.bid: " + browserSignals.bid;
+ if (browserSignals.modifiedBid !== undefined)
+ throw "Unexpected top-level browserSignals.modifiedBid: " + browserSignals.modifiedBid;
+ sendReportTo("${topLevelSellerReportURL}");` });
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfig);
+ await waitForObservedRequests(
+ uuid,
+ [bidderReportURL, componentSellerReportURL, topLevelSellerReportURL]);
+}, 'Component auction modified bid.');
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ let bidderReportURL = createBidderReportURL(uuid);
+ let componentSellerReportURL = createSellerReportURL(uuid, /*id=*/1);
+ let topLevelSellerReportURL = createSellerReportURL(uuid, /*id=*/2);
+
+ await joinInterestGroup(
+ test, uuid,
+ { biddingLogicURL: createBiddingScriptURL(
+ { allowComponentAuction: true,
+ bid: 5,
+ reportWin:
+ `if (browserSignals.bid !== 5)
+ throw "Unexpected bid: " + browserSignals.bid;
+ sendReportTo("${bidderReportURL}");`})});
+
+ let auctionConfig = createComponentAuctionConfig(uuid);
+
+ auctionConfig.componentAuctions[0].decisionLogicURL =
+ createDecisionScriptURL(
+ uuid,
+ { scoreAd:
+ `if (bid !== 5)
+ throw "Unexpected component bid: " + bid
+ return {desirability: 5, allowComponentAuction: true, bid: 5};`,
+ reportResult:
+ `if (browserSignals.bid !== 5)
+ throw "Unexpected component browserSignals.bid: " + browserSignals.bid;
+ if (browserSignals.modifiedBid !== 5)
+ throw "Unexpected component browserSignals.modifiedBid: " + browserSignals.modifiedBid;
+ sendReportTo("${componentSellerReportURL}");` });
+
+ auctionConfig.decisionLogicURL =
+ createDecisionScriptURL(
+ uuid,
+ { scoreAd:
+ `if (bid !== 5)
+ throw "Unexpected top-level bid: " + bid`,
+ reportResult:
+ `if (browserSignals.bid !== 5)
+ throw "Unexpected top-level browserSignals.bid: " + browserSignals.bid;
+ if (browserSignals.modifiedBid !== undefined)
+ throw "Unexpected top-level browserSignals.modifiedBid: " + browserSignals.modifiedBid;
+ sendReportTo("${topLevelSellerReportURL}");` });
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfig);
+ await waitForObservedRequests(
+ uuid,
+ [bidderReportURL, componentSellerReportURL, topLevelSellerReportURL]);
+}, 'Component auction modified bid to same value.');
+
+promise_test(async test => {
+ const uuid = generateUuid(test);
+
+ let bidderReportURL = createBidderReportURL(uuid);
+ let componentSellerReportURL = createSellerReportURL(uuid, /*id=*/1);
+ let topLevelSellerReportURL = createSellerReportURL(uuid, /*id=*/2);
+
+ await joinInterestGroup(
+ test, uuid,
+ { biddingLogicURL: createBiddingScriptURL(
+ { allowComponentAuction: true,
+ bid: 5,
+ reportWin:
+ `if (browserSignals.bid !== 5)
+ throw "Unexpected bid: " + browserSignals.bid;
+ sendReportTo("${bidderReportURL}");`})});
+
+ let auctionConfig = createComponentAuctionConfig(uuid);
+
+ auctionConfig.componentAuctions[0].decisionLogicURL =
+ createDecisionScriptURL(
+ uuid,
+ { scoreAd:
+ `if (bid !== 5)
+ throw "Unexpected component bid: " + bid`,
+ reportResult:
+ `if (browserSignals.bid !== 5)
+ throw "Unexpected component browserSignals.bid: " + browserSignals.bid;
+ if (browserSignals.modifiedBid !== undefined)
+ throw "Unexpected component browserSignals.modifiedBid: " + browserSignals.modifiedBid;
+ sendReportTo("${componentSellerReportURL}");` });
+
+ auctionConfig.decisionLogicURL =
+ createDecisionScriptURL(
+ uuid,
+ { scoreAd:
+ `if (bid !== 5)
+ throw "Unexpected top-level bid: " + bid
+ return {desirability: 5, allowComponentAuction: true, bid: 4};`,
+ reportResult:
+ `if (browserSignals.bid !== 5)
+ throw "Unexpected top-level browserSignals.bid: " + browserSignals.bid;
+ if (browserSignals.modifiedBid !== undefined)
+ throw "Unexpected top-level browserSignals.modifiedBid: " + browserSignals.modifiedBid;
+ sendReportTo("${topLevelSellerReportURL}");` });
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfig);
+ await waitForObservedRequests(
+ uuid,
+ [bidderReportURL, componentSellerReportURL, topLevelSellerReportURL]);
+}, 'Top-level auction cannot modify bid.');