summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/fledge/tentative/resources/fledge-util.sub.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/fledge/tentative/resources/fledge-util.sub.js')
-rw-r--r--testing/web-platform/tests/fledge/tentative/resources/fledge-util.sub.js210
1 files changed, 151 insertions, 59 deletions
diff --git a/testing/web-platform/tests/fledge/tentative/resources/fledge-util.sub.js b/testing/web-platform/tests/fledge/tentative/resources/fledge-util.sub.js
index 5819357e29..7be02e34ff 100644
--- a/testing/web-platform/tests/fledge/tentative/resources/fledge-util.sub.js
+++ b/testing/web-platform/tests/fledge/tentative/resources/fledge-util.sub.js
@@ -177,7 +177,7 @@ async function waitForObservedRequestsIgnoreDebugOnlyReports(
function createBiddingScriptURL(params = {}) {
let origin = params.origin ? params.origin : new URL(BASE_URL).origin;
let url = new URL(`${origin}${RESOURCE_PATH}bidding-logic.sub.py`);
- // These checks use "==" to ignore null and not provided arguments, while
+ // These checks use "!=" to ignore null and not provided arguments, while
// treating '' as a valid argument.
if (params.generateBid != null)
url.searchParams.append('generateBid', params.generateBid);
@@ -213,7 +213,7 @@ function createDecisionScriptURL(uuid, params = {}) {
let origin = params.origin ? params.origin : new URL(BASE_URL).origin;
let url = new URL(`${origin}${RESOURCE_PATH}decision-logic.sub.py`);
url.searchParams.append('uuid', uuid);
- // These checks use "==" to ignore null and not provided arguments, while
+ // These checks use "!=" to ignore null and not provided arguments, while
// treating '' as a valid argument.
if (params.scoreAd != null)
url.searchParams.append('scoreAd', params.scoreAd);
@@ -230,8 +230,8 @@ function createDecisionScriptURL(uuid, params = {}) {
// be last. "signalsParams" also has no effect, but is used by
// trusted-scoring-signals.py to affect the response.
function createRenderURL(uuid, script, signalsParams, origin) {
- // These checks use "==" to ignore null and not provided arguments, while
- // treating '' as a valid argument.
+ // These checks use "==" and "!=" to ignore null and not provided
+ // arguments, while treating '' as a valid argument.
if (origin == null)
origin = new URL(BASE_URL).origin;
let url = new URL(`${origin}${RESOURCE_PATH}fenced-frame.sub.py`);
@@ -260,6 +260,15 @@ function createInterestGroupForOrigin(uuid, origin,
};
}
+// Waits for the join command to complete. Adds cleanup command to `test` to
+// leave the interest group when the test completes.
+async function joinInterestGroupWithoutDefaults(test, interestGroup,
+ durationSeconds = 60) {
+ await navigator.joinAdInterestGroup(interestGroup, durationSeconds);
+ test.add_cleanup(
+ async () => { await navigator.leaveAdInterestGroup(interestGroup); });
+}
+
// Joins an interest group that, by default, is owned by the current frame's
// origin, is named DEFAULT_INTEREST_GROUP_NAME, has a bidding script that
// issues a bid of 9 with a renderURL of "https://not.checked.test/${uuid}",
@@ -271,12 +280,33 @@ function createInterestGroupForOrigin(uuid, origin,
// interest group.
async function joinInterestGroup(test, uuid, interestGroupOverrides = {},
durationSeconds = 60) {
- let interestGroup = createInterestGroupForOrigin(uuid, window.location.origin,
- interestGroupOverrides);
-
- await navigator.joinAdInterestGroup(interestGroup, durationSeconds);
- test.add_cleanup(
- async () => { await navigator.leaveAdInterestGroup(interestGroup) });
+ await joinInterestGroupWithoutDefaults(
+ test, createInterestGroupForOrigin(
+ uuid, window.location.origin, interestGroupOverrides),
+ durationSeconds);
+}
+
+// Joins a negative interest group with the specified owner, name, and
+// additionalBidKey. Because these are the only valid fields for a negative
+// interest groups, this function doesn't expose an 'overrides' parameter.
+// Adds cleanup command to `test` to leave the interest group when the test
+// completes.
+async function joinNegativeInterestGroup(
+ test, owner, name, additionalBidKey) {
+ let interestGroup = {
+ owner: owner,
+ name: name,
+ additionalBidKey: additionalBidKey
+ };
+ if (owner !== window.location.origin) {
+ let iframe = await createIframe(test, owner, 'join-ad-interest-group');
+ await runInFrame(
+ test, iframe,
+ `await joinInterestGroupWithoutDefaults(` +
+ `test_instance, ${JSON.stringify(interestGroup)})`);
+ } else {
+ await joinInterestGroupWithoutDefaults(test_instance, interestGroup);
+ }
}
// Similar to joinInterestGroup, but leaves the interest group instead.
@@ -487,6 +517,17 @@ async function runReportTest(test, uuid, codeToInsert, expectedReportURLs,
await waitForObservedRequests(uuid, expectedReportURLs);
}
+// Helper function for running a standard test of the additional bid and
+// negative targeting features. This helper verifies that the auction produces a
+// winner. It takes the following arguments:
+// - test/uuid: the test object and uuid from the test case (see generateUuid)
+// - buyers: array of strings, each a domain for a buyer participating in this
+// auction
+// - actionNonce: string, the auction nonce for this auction, typically
+// retrieved from a prior call to navigator.createAuctionNonce
+// - highestScoringOtherBid: the amount of the second-highest bid,
+// or zero if there's no second-highest bid
+// - winningAdditionalBidId: the label of the winning bid
async function runAdditionalBidTest(test, uuid, buyers, auctionNonce,
additionalBidsPromise,
highestScoringOtherBid,
@@ -516,7 +557,7 @@ async function runInFrame(test, child_window, script, param) {
let promise = new Promise(function(resolve, reject) {
function WaitForMessage(event) {
- if (event.data.messageUuid != messageUuid)
+ if (event.data.messageUuid !== messageUuid)
return;
receivedResponse = event.data;
if (event.data.result === 'success') {
@@ -548,7 +589,7 @@ async function createFrame(test, origin, is_iframe = true, permissions = null) {
`${origin}${RESOURCE_PATH}subordinate-frame.sub.html?uuid=${frameUuid}`;
let promise = new Promise(function(resolve, reject) {
function WaitForMessage(event) {
- if (event.data.messageUuid != frameUuid)
+ if (event.data.messageUuid !== frameUuid)
return;
if (event.data.result === 'load complete') {
resolve();
@@ -662,79 +703,130 @@ function directFromSellerSignalsValidatorCode(uuid, expectedSellerSignals,
return {
// Seller worklets
scoreAd:
- `if (directFromSellerSignals === null ||
+ `if (directFromSellerSignals == null ||
directFromSellerSignals.sellerSignals !== ${expectedSellerSignals} ||
directFromSellerSignals.auctionSignals !== ${expectedAuctionSignals} ||
- Object.keys(directFromSellerSignals).length != 2) {
+ Object.keys(directFromSellerSignals).length !== 2) {
throw 'Failed to get expected directFromSellerSignals in scoreAd(): ' +
JSON.stringify(directFromSellerSignals);
}`,
reportResultSuccessCondition:
- `directFromSellerSignals !== null &&
+ `directFromSellerSignals != null &&
directFromSellerSignals.sellerSignals === ${expectedSellerSignals} &&
directFromSellerSignals.auctionSignals === ${expectedAuctionSignals} &&
- Object.keys(directFromSellerSignals).length == 2`,
+ Object.keys(directFromSellerSignals).length === 2`,
reportResult:
`sendReportTo("${createSellerReportURL(uuid)}");`,
// Bidder worklets
generateBid:
- `if (directFromSellerSignals === null ||
+ `if (directFromSellerSignals == null ||
directFromSellerSignals.perBuyerSignals !== ${expectedPerBuyerSignals} ||
directFromSellerSignals.auctionSignals !== ${expectedAuctionSignals} ||
- Object.keys(directFromSellerSignals).length != 2) {
+ Object.keys(directFromSellerSignals).length !== 2) {
throw 'Failed to get expected directFromSellerSignals in generateBid(): ' +
JSON.stringify(directFromSellerSignals);
}`,
reportWinSuccessCondition:
- `directFromSellerSignals !== null &&
+ `directFromSellerSignals != null &&
directFromSellerSignals.perBuyerSignals === ${expectedPerBuyerSignals} &&
directFromSellerSignals.auctionSignals === ${expectedAuctionSignals} &&
- Object.keys(directFromSellerSignals).length == 2`,
+ Object.keys(directFromSellerSignals).length === 2`,
reportWin:
`sendReportTo("${createBidderReportURL(uuid)}");`,
};
}
-// Creates an additional bid with the given parameters. This additional bid
-// specifies a biddingLogicURL that provides an implementation of
-// reportAdditionalBidWin that triggers a sendReportTo() to the bidder report
-// URL of the winning additional bid. Additional bids are described in more
-// detail at
-// https://github.com/WICG/turtledove/blob/main/FLEDGE.md#6-additional-bids.
-function createAdditionalBid(uuid, auctionNonce, seller, buyer, interestGroupName, bidAmount,
- additionalBidOverrides = {}) {
- return {
- interestGroup: {
- name: interestGroupName,
- biddingLogicURL: createBiddingScriptURL(
- {
- origin: buyer,
- reportAdditionalBidWin: `sendReportTo("${createBidderReportURL(uuid, interestGroupName)}");`
- }),
- owner: buyer
- },
- bid: {
- ad: ['metadata'],
- bid: bidAmount,
- render: createRenderURL(uuid)
- },
- auctionNonce: auctionNonce,
- seller: seller,
- ...additionalBidOverrides
+let additionalBidHelper = function() {
+ // Creates an additional bid with the given parameters. This additional bid
+ // specifies a biddingLogicURL that provides an implementation of
+ // reportAdditionalBidWin that triggers a sendReportTo() to the bidder report
+ // URL of the winning additional bid. Additional bids are described in more
+ // detail at
+ // https://github.com/WICG/turtledove/blob/main/FLEDGE.md#6-additional-bids.
+ function createAdditionalBid(uuid, auctionNonce, seller, buyer, interestGroupName, bidAmount,
+ additionalBidOverrides = {}) {
+ return {
+ interestGroup: {
+ name: interestGroupName,
+ biddingLogicURL: createBiddingScriptURL(
+ {
+ origin: buyer,
+ reportAdditionalBidWin: `sendReportTo("${createBidderReportURL(uuid, interestGroupName)}");`
+ }),
+ owner: buyer
+ },
+ bid: {
+ ad: ['metadata'],
+ bid: bidAmount,
+ render: createRenderURL(uuid)
+ },
+ auctionNonce: auctionNonce,
+ seller: seller,
+ ...additionalBidOverrides
+ };
}
-}
-// Fetch some number of additional bid from a seller and verify that the
-// 'Ad-Auction-Additional-Bid' header is not visible in this JavaScript context.
-// The `additionalBids` parameter is a list of additional bids.
-async function fetchAdditionalBids(seller, additionalBids) {
- const url = new URL(`${seller}${RESOURCE_PATH}additional-bids.py`);
- url.searchParams.append('additionalBids', JSON.stringify(additionalBids));
- const response = await fetch(url.href, {adAuctionHeaders: true});
+ // Gets the testMetadata for an additional bid, initializing it if needed.
+ function getAndMaybeInitializeTestMetadata(additionalBid) {
+ if (additionalBid.testMetadata === undefined) {
+ additionalBid.testMetadata = {};
+ }
+ return additionalBid.testMetadata;
+ }
- assert_equals(response.status, 200, 'Failed to fetch additional bid: ' + await response.text());
- assert_false(
- response.headers.has('Ad-Auction-Additional-Bid'),
- 'Header "Ad-Auction-Additional-Bid" should not be available in JavaScript context.');
-}
+ // Tells the additional bid endpoint to correctly sign the additional bid with
+ // the given secret keys before returning that as a signed additional bid.
+ function signWithSecretKeys(additionalBid, secretKeys) {
+ getAndMaybeInitializeTestMetadata(additionalBid).
+ secretKeysForValidSignatures = secretKeys;
+ }
+
+ // Tells the additional bid endpoint to incorrectly sign the additional bid with
+ // the given secret keys before returning that as a signed additional bid. This
+ // is used for testing the behavior when the auction encounters an invalid
+ // signature.
+ function incorrectlySignWithSecretKeys(additionalBid, secretKeys) {
+ getAndMaybeInitializeTestMetadata(additionalBid).
+ secretKeysForInvalidSignatures = secretKeys;
+ }
+
+ // Adds a single negative interest group to an additional bid, as described at:
+ // https://github.com/WICG/turtledove/blob/main/FLEDGE.md#622-how-additional-bids-specify-their-negative-interest-groups
+ function addNegativeInterestGroup(additionalBid, negativeInterestGroup) {
+ additionalBid["negativeInterestGroup"] = negativeInterestGroup;
+ }
+
+ // Adds multiple negative interest groups to an additional bid, as described at:
+ // https://github.com/WICG/turtledove/blob/main/FLEDGE.md#622-how-additional-bids-specify-their-negative-interest-groups
+ function addNegativeInterestGroups(additionalBid, negativeInterestGroups,
+ joiningOrigin) {
+ additionalBid["negativeInterestGroups"] = {
+ joiningOrigin: joiningOrigin,
+ interestGroupNames: negativeInterestGroups
+ };
+ }
+
+ // Fetch some number of additional bid from a seller and verify that the
+ // 'Ad-Auction-Additional-Bid' header is not visible in this JavaScript context.
+ // The `additionalBids` parameter is a list of additional bids.
+ async function fetchAdditionalBids(seller, additionalBids) {
+ const url = new URL(`${seller}${RESOURCE_PATH}additional-bids.py`);
+ url.searchParams.append('additionalBids', JSON.stringify(additionalBids));
+ const response = await fetch(url.href, {adAuctionHeaders: true});
+
+ assert_equals(response.status, 200, 'Failed to fetch additional bid: ' + await response.text());
+ assert_false(
+ response.headers.has('Ad-Auction-Additional-Bid'),
+ 'Header "Ad-Auction-Additional-Bid" should not be available in JavaScript context.');
+ }
+
+ return {
+ createAdditionalBid: createAdditionalBid,
+ signWithSecretKeys: signWithSecretKeys,
+ incorrectlySignWithSecretKeys: incorrectlySignWithSecretKeys,
+ addNegativeInterestGroup: addNegativeInterestGroup,
+ addNegativeInterestGroups: addNegativeInterestGroups,
+ fetchAdditionalBids: fetchAdditionalBids
+ };
+}();