Skip to content

Commit

Permalink
[FLEDGE] Pass trustedBiddingSignalsSlotSizeMode to generateBid().
Browse files Browse the repository at this point in the history
This CL adds a trustedBiddingSignalsSlotSizeMode field to the
InterestGroup object passed to generateBid().

It also adds a WPT test fixture that can be used to test InterestGroup
values passed to generateBid() in general.

Fixed: 1506238
Change-Id: I7c03c058beecb070c0374b3a7e7a8f6159f73207
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5105671
Reviewed-by: Russ Hamilton <behamilton@google.com>
Commit-Queue: Matt Menke <mmenke@chromium.org>
Reviewed-by: Joe Mason <joenotcharles@google.com>
Cr-Commit-Position: refs/heads/main@{#1237800}
  • Loading branch information
Matt Menke authored and chromium-wpt-export-bot committed Dec 14, 2023
1 parent 9cc0bbf commit 0bd1bde
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 25 deletions.
177 changes: 177 additions & 0 deletions fledge/tentative/interest-group-passed-to-generate-bid.https.window.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// META: script=/resources/testdriver.js
// META: script=/common/utils.js
// META: script=resources/fledge-util.sub.js
// META: script=/common/subset-tests.js
// META: timeout=long
// META: variant=?1-5
// META: variant=?6-10
// META: variant=?11-15
// META: variant=?16-last

"use strict;"

// These tests focus on making sure InterestGroup fields are passed to generateBid(),
// and are normalized if necessary. This test does not check the behaviors of the
// fields.

const makeTest = ({
// Test name.
name,
// InterestGroup field name.
fieldName,
// InterestGroup field value, both expected in worklets and acution in the
// auction. If undefined, value will not be set in interestGroup, and will
// be expected to also not be set in the interestGroup passed to generateBid().
fieldValue,
// Additional values to use in the InterestGroup passed to joinInterestGroup().
// If it contains a value for the key specified in `fieldName`, that takes
// precedent over `fieldValue`.
interestGroupOverrides = {}
}) => {
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);

if (!(fieldName in interestGroupOverrides) && fieldValue !== undefined)
interestGroupOverrides[fieldName] = fieldValue;

let comparison = `deepEquals(interestGroup["${fieldName}"], ${JSON.stringify(fieldValue)})`;
// In the case it's undefined, require value not to be set.
if (fieldValue === undefined)
comparison = `!("${fieldName}" in interestGroup)`;

// Prefer to use `interestGroupOverrides.owner` if present. Treat it as a URL
// and then convert it to an origin because one test passes in a URL.
let origin = location.origin;
if (interestGroupOverrides.owner)
origin = new URL(interestGroupOverrides.owner).origin;

interestGroupOverrides.biddingLogicURL =
createBiddingScriptURL(
{ origin: origin,
generateBid:
`if (!${comparison})
throw "Unexpected value: " + JSON.stringify(interestGroup["${fieldName}"]);`
});
if (origin !== location.origin) {
await joinCrossOriginInterestGroup(test, uuid, origin, interestGroupOverrides);
} else {
await joinInterestGroup(test, uuid, interestGroupOverrides);
}

await runBasicFledgeTestExpectingWinner(test, uuid, {interestGroupBuyers: [origin]});
}, name);
};

makeTest({
name: 'InterestGroup.owner.',
fieldName: 'owner',
fieldValue: OTHER_ORIGIN1
});

makeTest({
name: 'InterestGroup.owner with non-normalized origin.',
fieldName: 'owner',
fieldValue: OTHER_ORIGIN1,
interestGroupOverrides: {seller: ` ${OTHER_ORIGIN1.toUpperCase()} `}
});

makeTest({
name: 'InterestGroup.owner is URL.',
fieldName: 'owner',
fieldValue: OTHER_ORIGIN1,
interestGroupOverrides: {seller: OTHER_ORIGIN1 + "/Foopy"}
});

makeTest({
name: 'InterestGroup.trustedBiddingSignalsURL not set.',
fieldName: 'trustedBiddingSignalsURL',
fieldValue: undefined
});

makeTest({
name: 'InterestGroup.trustedBiddingSignalsURL.',
fieldName: 'trustedBiddingSignalsURL',
fieldValue: `${OTHER_ORIGIN1}${BASE_PATH}this-file-does-not-exist.json`,
interestGroupOverrides: {owner: OTHER_ORIGIN1}
});

makeTest({
name: 'InterestGroup.trustedBiddingSignalsURL with non-normalized value.',
fieldName: 'trustedBiddingSignalsURL',
fieldValue: `${OTHER_ORIGIN1}${BASE_PATH}this-file-does-not-exist.json`,
interestGroupOverrides: {
owner: OTHER_ORIGIN1,
trustedScoringSignalsURL:
`${OTHER_ORIGIN1.toUpperCase()}${BASE_PATH}this-file-does-not-exist.json`
}
});

makeTest({
name: 'InterestGroup.trustedBiddingSignalsKeys not set.',
fieldName: 'trustedBiddingSignalsKeys',
fieldValue: undefined
});

makeTest({
name: 'InterestGroup.name.',
fieldName: 'name',
fieldValue: 'Jim'
});

makeTest({
name: 'InterestGroup.name with unicode characters.',
fieldName: 'name',
fieldValue: '\u2665'
});

makeTest({
name: 'InterestGroup.trustedBiddingSignalsKeys.',
fieldName: 'trustedBiddingSignalsKeys',
fieldValue: ['a', ' b ', 'c', '1', '%20', '3', '\u2665']
});

makeTest({
name: 'InterestGroup.trustedBiddingSignalsKeys with non-normalized values.',
fieldName: 'trustedBiddingSignalsKeys',
fieldValue: ['1', '2', '3'],
interestGroupOverrides: { trustedBiddingSignalsKeys: [1, 0x2, '3'] }
});

makeTest({
name: 'InterestGroup.trustedBiddingSignalsSlotSizeMode empty.',
fieldName: 'trustedBiddingSignalsSlotSizeMode',
fieldValue: 'none',
interestGroupOverrides: { trustedBiddingSignalsSlotSizeMode: undefined }
});

makeTest({
name: 'InterestGroup.trustedBiddingSignalsSlotSizeMode none.',
fieldName: 'trustedBiddingSignalsSlotSizeMode',
fieldValue: 'none'
});

makeTest({
name: 'InterestGroup.trustedBiddingSignalsSlotSizeMode slot-size.',
fieldName: 'trustedBiddingSignalsSlotSizeMode',
fieldValue: 'slot-size'
});

makeTest({
name: 'InterestGroup.trustedBiddingSignalsSlotSizeMode all-slots-requested-sizes.',
fieldName: 'trustedBiddingSignalsSlotSizeMode',
fieldValue: 'all-slots-requested-sizes'
});

makeTest({
name: 'InterestGroup.trustedBiddingSignalsSlotSizeMode unrecognized value.',
fieldName: 'trustedBiddingSignalsSlotSizeMode',
fieldValue: 'none',
interestGroupOverrides: { trustedBiddingSignalsSlotSizeMode: 'unrecognized value' }
});

makeTest({
name: 'InterestGroup.nonStandardField.',
fieldName: 'nonStandardField',
fieldValue: undefined,
interestGroupOverrides: {nonStandardField: 'This value should not be passed to worklets'}
});
7 changes: 5 additions & 2 deletions fledge/tentative/resources/bidding-logic.sub.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from pathlib import Path

# General bidding logic script. Depending on query parameters, it can
# simulate a variety of network errors, and its generateBid() and
# reportWin() functions can have arbitrary Javascript code injected
Expand Down Expand Up @@ -30,9 +32,10 @@ def main(request, response):
elif error != b"no-allow-fledge":
response.headers.set(b"Ad-Auction-Allowed", b"true")

body = b''
if error == b"no-body":
return body
return b''

body = (Path(__file__).parent.resolve() / 'worklet-helpers.js').read_text().encode("ASCII")
if error != b"no-generateBid":
# Use bid query param if present. Otherwise, use a bid of 9.
bid = (request.GET.first(b"bid", None) or b"9").decode("ASCII")
Expand Down
28 changes: 5 additions & 23 deletions fledge/tentative/resources/decision-logic.sub.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from pathlib import Path

# General decision logic script. Depending on query parameters, it can
# simulate a variety of network errors, and its scoreAd() and
# reportResult() functions can have arbitrary Javascript code injected
Expand Down Expand Up @@ -30,32 +32,12 @@ def main(request, response):
elif error != b"no-allow-fledge":
response.headers.set(b"Ad-Auction-Allowed", b"true")

body = b''
if error == b"no-body":
return body
return b''

body = (Path(__file__).parent.resolve() / 'worklet-helpers.js').read_text().encode("ASCII")
if error != b"no-scoreAd":
body += b"""
// Comparison function checks if two arguments are the same.
// Not intended for use on anything other than built-in types
// (Arrays, objects, and primitive types).
function deepEquals(a, b) {
if (typeof a !== typeof b)
return false;
if (typeof a !== 'object' || a === null || b === null)
return a === b;
let aKeys = Object.keys(a);
if (aKeys.length != Object.keys(b).length)
return false;
for (key in aKeys) {
if (a.hasOwnProperty(key) != b.hasOwnProperty(key) ||
!deepEquals(a[key], b[key])) {
return false;
}
}
return true;
}
function scoreAd(adMetadata, bid, auctionConfig, trustedScoringSignals,
browserSignals, directFromSellerSignals) {
// Don't bid on interest group with the wrong uuid. This is to prevent
Expand Down
23 changes: 23 additions & 0 deletions fledge/tentative/resources/worklet-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// This file contains helper methods that are appended to the start of bidder
// and seller worklets.

// Comparison function that checks if two arguments are the same.
// Not intended for use on anything other than built-in types
// (Arrays, objects, and primitive types).
function deepEquals(a, b) {
if (typeof a !== typeof b)
return false;
if (typeof a !== 'object' || a === null || b === null)
return a === b;

let aKeys = Object.keys(a);
if (aKeys.length != Object.keys(b).length)
return false;
for (key in aKeys) {
if (a.hasOwnProperty(key) != b.hasOwnProperty(key) ||
!deepEquals(a[key], b[key])) {
return false;
}
}
return true;
}

0 comments on commit 0bd1bde

Please sign in to comment.