blob: 21b3f9af3a5a21be0d0c84ef0610a9db34c8a33d [file] [log] [blame] [edit]
// 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-4
// META: variant=?5-8
// META: variant=?9-12
// META: variant=?13-16
// META: variant=?17-last
'use strict;'
const ORIGIN = window.location.origin;
// The tests in this file focus on calls to runAdAuction involving currency
// handling.
// Joins an interest group that bids 9USD on window.location.origin, and one
// that bids 10CAD on OTHER_ORIGIN1, each with a reportWin() report.
async function joinTwoCurrencyGroups(test, uuid) {
const reportWinURL = createBidderReportURL(uuid, 'USD');
const biddingURL = createBiddingScriptURL(
{bidCurrency: 'USD', reportWin: `sendReportTo('${reportWinURL}')`});
await joinInterestGroup(test, uuid, {biddingLogicURL: biddingURL});
const otherReportWinURL = createBidderReportURL(uuid, 'CAD', OTHER_ORIGIN1);
const otherBiddingURL = createBiddingScriptURL({
origin: OTHER_ORIGIN1,
bid: 10,
bidCurrency: 'CAD',
reportWin: `sendReportTo('${otherReportWinURL}')`
});
await joinCrossOriginInterestGroup(
test, uuid, OTHER_ORIGIN1, {biddingLogicURL: otherBiddingURL});
}
function createBiddingScriptURLWithCurrency(uuid, currency) {
return createBiddingScriptURL({
bidCurrency: currency,
allowComponentAuction: true,
reportWin: `
sendReportTo('${createBidderReportURL(uuid, /*id=*/ '')}' +
browserSignals.bid + encodeURIComponent(browserSignals.bidCurrency));`,
});
}
function createDecisionURLExpectCurrency(uuid, currencyInScore) {
return createDecisionScriptURL(uuid, {
scoreAd: `
if (browserSignals.bidCurrency !== '${currencyInScore}')
throw 'Wrong currency';`,
reportResult: `
sendReportTo('${createSellerReportURL(uuid, /*id=*/ '')}' +
browserSignals.bid + encodeURIComponent(browserSignals.bidCurrency) );`,
});
}
async function runCurrencyComponentAuction(test, uuid, params = {}) {
let auctionConfigOverrides = {
interestGroupBuyers: [],
decisionLogicURL: createDecisionScriptURL(uuid, {
reportResult: `
sendReportTo('${createSellerReportURL(uuid, 'top_')}' +
browserSignals.bid + encodeURIComponent(browserSignals.bidCurrency))`,
...params.topLevelSellerScriptParamsOverride
}),
componentAuctions: [{
seller: ORIGIN,
decisionLogicURL: createDecisionScriptURL(uuid, {
reportResult: `
sendReportTo('${createSellerReportURL(uuid, 'component_')}' +
browserSignals.bid + encodeURIComponent(browserSignals.bidCurrency))`,
...params.componentSellerScriptParamsOverride
}),
interestGroupBuyers: [ORIGIN],
...params.componentAuctionConfigOverrides
}],
...params.topLevelAuctionConfigOverrides
};
return await runBasicFledgeAuction(test, uuid, auctionConfigOverrides);
}
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURL({bidCurrency: 'usd'})});
await runBasicFledgeTestExpectingNoWinner(test, uuid);
}, 'Returning bid with invalid currency.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
await runBasicFledgeAuctionAndNavigate(
test, uuid,
{decisionLogicURL: createDecisionURLExpectCurrency(uuid, 'USD')});
await waitForObservedRequests(uuid, [
createSellerReportURL(uuid, '9???'), createBidderReportURL(uuid, '9???')
]);
}, 'Returning bid with currency, configuration w/o currency.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, undefined)});
await runBasicFledgeAuctionAndNavigate(test, uuid, {
perBuyerCurrencies: {'*': 'USD'},
decisionLogicURL: createDecisionURLExpectCurrency(uuid, '???')
});
await waitForObservedRequests(uuid, [
createSellerReportURL(uuid, '9USD'), createBidderReportURL(uuid, '9USD')
]);
}, 'Returning bid w/o currency, configuration w/currency.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
await runBasicFledgeAuctionAndNavigate(test, uuid, {
perBuyerCurrencies: {'*': 'USD'},
decisionLogicURL: createDecisionURLExpectCurrency(uuid, 'USD')
});
await waitForObservedRequests(uuid, [
createSellerReportURL(uuid, '9USD'), createBidderReportURL(uuid, '9USD')
]);
}, 'Returning bid w/currency, configuration w/matching currency.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURL({bidCurrency: 'USD'})});
await runBasicFledgeTestExpectingNoWinner(
test, uuid, {perBuyerCurrencies: {'*': 'CAD'}});
}, 'Returning bid w/currency, configuration w/different currency.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinTwoCurrencyGroups(test, uuid);
let auctionConfigOverrides = {
interestGroupBuyers: [ORIGIN, OTHER_ORIGIN1],
perBuyerCurrencies: {}
};
auctionConfigOverrides.perBuyerCurrencies['*'] = 'USD';
auctionConfigOverrides.perBuyerCurrencies[OTHER_ORIGIN1] = 'CAD';
await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfigOverrides);
// Since the scoring script doesn't actually look at the currencies,
// We expect 10CAD to win because 10 > 9
await waitForObservedRequests(uuid, [
createBidderReportURL(uuid, 'CAD', OTHER_ORIGIN1),
createSellerReportURL(uuid)
]);
}, 'Different currencies for different origins, all match.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinTwoCurrencyGroups(test, uuid);
let auctionConfigOverrides = {
interestGroupBuyers: [ORIGIN, OTHER_ORIGIN1],
perBuyerCurrencies: {}
};
auctionConfigOverrides.perBuyerCurrencies[ORIGIN] = 'USD';
auctionConfigOverrides.perBuyerCurrencies[OTHER_ORIGIN1] = 'EUR';
await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfigOverrides);
// Since the configuration for CAD script expects EUR only the USD bid goes
// through.
await waitForObservedRequests(
uuid, [createBidderReportURL(uuid, 'USD'), createSellerReportURL(uuid)]);
}, 'Different currencies for different origins, USD one matches.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinTwoCurrencyGroups(test, uuid);
let auctionConfigOverrides = {
interestGroupBuyers: [ORIGIN, OTHER_ORIGIN1],
perBuyerCurrencies: {}
};
auctionConfigOverrides.perBuyerCurrencies['*'] = 'EUR';
}, 'Different currencies for different origins, none match.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let config = await runCurrencyComponentAuction(test, uuid, {
topLevelSellerScriptParamsOverride: {
scoreAd: `
if (browserSignals.bidCurrency !== 'USD')
throw 'Wrong currency';`
}
});
expectSuccess(config);
createAndNavigateFencedFrame(test, config);
// While scoring sees the original currency tag, reporting currency tags are
// config-based.
await waitForObservedRequests(uuid, [
createSellerReportURL(uuid, 'top_9???'),
createSellerReportURL(uuid, 'component_9???'),
createBidderReportURL(uuid, '9???')
]);
}, 'Multi-seller auction --- no currency restriction.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let config = await runCurrencyComponentAuction(test, uuid, {
componentAuctionConfigOverrides: {sellerCurrency: 'USD'},
topLevelSellerScriptParamsOverride: {
scoreAd: `
if (browserSignals.bidCurrency !== 'USD')
throw 'Wrong currency';`
}
});
expectSuccess(config);
createAndNavigateFencedFrame(test, config);
// Because component's sellerCurrency is USD, the bid it makes is seen to be
// in dollars by top-level reporting. That doesn't affect reporting in its
// own auction.
await waitForObservedRequests(uuid, [
createSellerReportURL(uuid, 'top_9USD'),
createSellerReportURL(uuid, 'component_9???'),
createBidderReportURL(uuid, '9???')
]);
}, 'Multi-seller auction --- component sellerCurrency matches bid.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let config = await runCurrencyComponentAuction(test, uuid, {
componentAuctionConfigOverrides: {sellerCurrency: 'EUR'},
componentSellerScriptParamsOverride: {
scoreAd: `
return {desirability: 2 * bid, allowComponentAuction: true,
bid: 1.5 * bid, bidCurrency: 'EUR'}
`
},
topLevelSellerScriptParamsOverride: {
scoreAd: `
if (browserSignals.bidCurrency !== 'EUR')
throw 'Wrong currency';`
}
});
expectSuccess(config);
createAndNavigateFencedFrame(test, config);
// Because component's sellerCurrency is USD, the bid it makes is seen to be
// in dollars by top-level reporting. That doesn't affect reporting in its
// own auction.
await waitForObservedRequests(uuid, [
createSellerReportURL(uuid, 'top_13.5EUR'),
createSellerReportURL(uuid, 'component_9???'),
createBidderReportURL(uuid, '9???')
]);
}, 'Multi-seller auction --- component scoreAd modifies bid into its sellerCurrency.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let config = await runCurrencyComponentAuction(test, uuid, {
componentAuctionConfigOverrides: {sellerCurrency: 'EUR'},
componentSellerScriptParamsOverride: {
scoreAd: `
return {desirability: 2 * bid, allowComponentAuction: true,
bid: 1.5 * bid}
`
},
topLevelSellerScriptParamsOverride: {
scoreAd: `
// scoreAd sees what's actually passed in.
if (browserSignals.bidCurrency !== '???')
throw 'Wrong currency';`
}
});
expectSuccess(config);
createAndNavigateFencedFrame(test, config);
await waitForObservedRequests(uuid, [
createSellerReportURL(uuid, 'top_13.5EUR'),
createSellerReportURL(uuid, 'component_9???'),
createBidderReportURL(uuid, '9???')
]);
}, 'Multi-seller auction --- component scoreAd modifies bid, no explicit currency.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let config = await runCurrencyComponentAuction(test, uuid, {
componentAuctionConfigOverrides:
{sellerCurrency: 'EUR', perBuyerCurrencies: {'*': 'USD'}},
componentSellerScriptParamsOverride: {
scoreAd: `
return {desirability: 2 * bid, allowComponentAuction: true,
bid: 1.5 * bid}
`
},
topLevelSellerScriptParamsOverride: {
scoreAd: `
// scoreAd sees what's actually passed in.
if (browserSignals.bidCurrency !== '???')
throw 'Wrong currency';`
}
});
expectSuccess(config);
createAndNavigateFencedFrame(test, config);
await waitForObservedRequests(uuid, [
createSellerReportURL(uuid, 'top_13.5EUR'),
createSellerReportURL(uuid, 'component_9USD'),
createBidderReportURL(uuid, '9USD')
]);
}, 'Multi-seller auction --- component scoreAd modifies bid, bidder has bidCurrency.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let config = await runCurrencyComponentAuction(test, uuid, {
componentAuctionConfigOverrides: {perBuyerCurrencies: {'*': 'USD'}},
componentSellerScriptParamsOverride: {
scoreAd: `
return {desirability: 2 * bid, allowComponentAuction: true,
bid: 1.5 * bid}
`
},
topLevelSellerScriptParamsOverride: {
scoreAd: `
// scoreAd sees what's actually passed in.
if (browserSignals.bidCurrency !== '???')
throw 'Wrong currency';`
}
});
expectSuccess(config);
createAndNavigateFencedFrame(test, config);
await waitForObservedRequests(uuid, [
createSellerReportURL(uuid, 'top_13.5???'),
createSellerReportURL(uuid, 'component_9USD'),
createBidderReportURL(uuid, '9USD')
]);
}, 'Multi-seller auction --- only bidder currency specified.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let result = await runCurrencyComponentAuction(test, uuid, {
componentAuctionConfigOverrides: {sellerCurrency: 'EUR'},
componentSellerScriptParamsOverride: {
scoreAd: `
return {desirability: 2 * bid, allowComponentAuction: true,
bid: 1.5 * bid, bidCurrency: 'CAD'}
`
}
});
expectNoWinner(result);
}, 'Multi-seller auction --- component scoreAd modifies bid to wrong currency.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let topLevelConfigOverride = {perBuyerCurrencies: {}};
topLevelConfigOverride.perBuyerCurrencies[ORIGIN] = 'USD';
let config = await runCurrencyComponentAuction(test, uuid, {
topLevelAuctionConfigOverrides: topLevelConfigOverride,
topLevelSellerScriptParamsOverride: {
scoreAd: `
if (browserSignals.bidCurrency !== 'USD')
throw 'Wrong currency';`
}
});
expectSuccess(config);
createAndNavigateFencedFrame(test, config);
// Because component is constrained by perBuyerCurrencies for it on top-level
// to USD, the bid it makes is seen to be in dollars by top-level reporting.
// That doesn't affect reporting in its own auction.
await waitForObservedRequests(uuid, [
createSellerReportURL(uuid, 'top_9USD'),
createSellerReportURL(uuid, 'component_9???'),
createBidderReportURL(uuid, '9???')
]);
}, 'Multi-seller auction --- top-level perBuyerCurrencies matches bid.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let topLevelConfigOverride = {perBuyerCurrencies: {}};
topLevelConfigOverride.perBuyerCurrencies[ORIGIN] = 'USD';
let config = await runCurrencyComponentAuction(test, uuid, {
componentAuctionConfigOverrides: {sellerCurrency: 'USD'},
topLevelAuctionConfigOverrides: topLevelConfigOverride,
topLevelSellerScriptParamsOverride: {
scoreAd: `
if (browserSignals.bidCurrency !== 'USD')
throw 'Wrong currency';`
}
});
expectSuccess(config);
createAndNavigateFencedFrame(test, config);
// Because component is constrained by perBuyerCurrencies for it on top-level
// to USD, the bid it makes is seen to be in dollars by top-level reporting.
// That doesn't affect reporting in its own auction.
await waitForObservedRequests(uuid, [
createSellerReportURL(uuid, 'top_9USD'),
createSellerReportURL(uuid, 'component_9???'),
createBidderReportURL(uuid, '9???')
]);
}, 'Multi-seller auction --- consistent sellerConfig and top-level perBuyerCurrencies.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let topLevelConfigOverride = {perBuyerCurrencies: {}};
topLevelConfigOverride.perBuyerCurrencies[ORIGIN] = 'EUR';
let result = await runCurrencyComponentAuction(test, uuid, {
componentAuctionConfigOverrides: {sellerCurrency: 'USD'},
topLevelAuctionConfigOverrides: topLevelConfigOverride,
topLevelSellerScriptParamsOverride: {
scoreAd: `
if (browserSignals.bidCurrency !== 'USD')
throw 'Wrong currency';`
}
});
expectNoWinner(result);
}, 'Multi-seller auction --- inconsistent sellerConfig and top-level perBuyerCurrencies.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let topLevelConfigOverride = {perBuyerCurrencies: {}};
topLevelConfigOverride.perBuyerCurrencies[ORIGIN] = 'EUR';
let result = await runCurrencyComponentAuction(
test, uuid, {componentAuctionConfigOverrides: topLevelConfigOverride});
expectNoWinner(result);
}, 'Multi-seller auction --- top-level perBuyerCurrencies different from bid.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(
test, uuid,
{biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')});
let result = await runCurrencyComponentAuction(
test, uuid, {componentAuctionConfigOverrides: {sellerCurrency: 'EUR'}});
expectNoWinner(result);
}, 'Multi-seller auction --- component sellerCurrency different from bid.');
// TODO: highestScoringOtherBid bid stuff:
// --- combination of sellerCurrency on/off, different conversion cases.
// Rules on conversion. Not strictly highestScoringOtherBid, but it makes it
// easier to check.
//
// PrivateAggregation stuff.