// 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-20 // META: variant=?21-24 // META: variant=?25-28 // META: variant=?29-32 // META: variant=?33-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 + browserSignals.bidCurrency);`, }); } // Creates a component-auction eligible bidding script returning a bid `bid` in // currency `currency`. It provides a reporting handler that logs bid and // highestScoringOtherBid along with their currencies. function createBiddingScriptURLForHighestScoringOther(uuid, bid, currency) { return createBiddingScriptURL({ bid: bid, bidCurrency: currency, allowComponentAuction: true, generateBid: ` forDebuggingOnly.reportAdAuctionWin( '${createBidderReportURL(uuid, /*id=*/ 'dbg_')}' + '\${winningBid}\${winningBidCurrency}_' + '\${highestScoringOtherBid}\${highestScoringOtherBidCurrency}');`, reportWin: ` sendReportTo( '${createBidderReportURL(uuid, /*id=*/ '')}' + browserSignals.bid + browserSignals.bidCurrency + '_' + browserSignals.highestScoringOtherBid + browserSignals.highestScoringOtherBidCurrency);`, }); } function createDecisionURLExpectCurrency(uuid, currencyInScore) { return createDecisionScriptURL(uuid, { scoreAd: ` if (browserSignals.bidCurrency !== '${currencyInScore}') throw 'Wrong currency';`, reportResult: ` sendReportTo('${createSellerReportURL(uuid, /*id=*/ '')}' + browserSignals.bid + browserSignals.bidCurrency);`, }); } // Creates a component-auction seller script, which by default just scores // bid * 2, but the `conversion` argument can be used to customize bid // modification and currenct conversion. // // The script provides a reporting handler that logs bid and // highestScoringOtherBid along with their currencies as well as `suffix`. function createDecisionURLForHighestScoringOther( uuid, conversion = '', suffix = '') { return createDecisionScriptURL(uuid, { scoreAd: ` forDebuggingOnly.reportAdAuctionWin( '${createSellerReportURL(uuid, /*id=*/ 'dbg_')}' + '${suffix}' + '\${winningBid}\${winningBidCurrency}_' + '\${highestScoringOtherBid}\${highestScoringOtherBidCurrency}'); let converted = undefined; let modified = undefined; let modifiedCurrency = undefined; ${conversion} return {desirability: 2 * bid, incomingBidInSellerCurrency: converted, bid: modified, bidCurrency: modifiedCurrency, allowComponentAuction: true}; `, reportResult: ` sendReportTo( '${createSellerReportURL(uuid, /*id=*/ '')}' + '${suffix}' + browserSignals.bid + browserSignals.bidCurrency + '_' + browserSignals.highestScoringOtherBid + browserSignals.highestScoringOtherBidCurrency);`, }); } // Joins groups for 9USD and 10USD, with reporting including // highestScoringOtherBid. async function joinTwoGroupsForHighestScoringOther(test, uuid) { await joinInterestGroup(test, uuid, { name: 'group-9USD', biddingLogicURL: createBiddingScriptURLForHighestScoringOther(uuid, /*bid=*/ 9, 'USD') }); await joinInterestGroup(test, uuid, { name: 'group-10USD', biddingLogicURL: createBiddingScriptURLForHighestScoringOther(uuid, /*bid=*/ 10, 'USD') }); } async function runCurrencyComponentAuction(test, uuid, params = {}) { let auctionConfigOverrides = { interestGroupBuyers: [], decisionLogicURL: createDecisionScriptURL(uuid, { reportResult: ` sendReportTo('${createSellerReportURL(uuid, 'top_')}' + browserSignals.bid + browserSignals.bidCurrency)`, ...params.topLevelSellerScriptParamsOverride }), componentAuctions: [{ seller: ORIGIN, decisionLogicURL: createDecisionScriptURL(uuid, { reportResult: ` sendReportTo('${createSellerReportURL(uuid, 'component_')}' + browserSignals.bid + browserSignals.bidCurrency)`, ...params.componentSellerScriptParamsOverride }), interestGroupBuyers: [ORIGIN], ...params.componentAuctionConfigOverrides }], ...params.topLevelAuctionConfigOverrides }; return await runBasicFledgeAuction(test, uuid, auctionConfigOverrides); } // Runs a component auction with reporting scripts that report bid and // highestScoringOtherBid, along with their currencies. // // Customization points in `params` are: // componentAuctionConfigOverrides, topLevelAuctionConfigOverrides: // edit auctionConfig for given auction level. // // topLevelConversion and componentConversion: // Permit customizing how the scoring function does currency conversiona and // bid modification. See createDecisionURLForHighestScoringOther(). async function runCurrencyComponentAuctionForHighestScoringOther( test, uuid, params = {}) { let auctionConfigOverrides = { interestGroupBuyers: [], decisionLogicURL: createDecisionURLForHighestScoringOther( uuid, params.topLevelConversion || '', 'top_'), componentAuctions: [{ seller: ORIGIN, decisionLogicURL: createDecisionURLForHighestScoringOther( uuid, params.componentConversion || '', 'component_'), 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 config = await runCurrencyComponentAuction(test, uuid, { componentAuctionConfigOverrides: {perBuyerCurrencies: {'*': 'USD'}}, componentSellerScriptParamsOverride: { scoreAd: ` return {desirability: 2 * bid, allowComponentAuction: true, bid: 1.5 * bid, bidCurrency: 'CAD'} ` }, topLevelSellerScriptParamsOverride: { scoreAd: ` // scoreAd sees what's actually passed in. if (browserSignals.bidCurrency !== 'CAD') 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 in config, component uses explicit currency.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinInterestGroup(test, uuid, { biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, /*bidCurrency=*/ undefined) }); let config = await runCurrencyComponentAuction(test, uuid, { componentAuctionConfigOverrides: {sellerCurrency: 'CAD'}, componentSellerScriptParamsOverride: { scoreAd: ` return {desirability: 2 * bid, allowComponentAuction: true, incomingBidInSellerCurrency: 12345} ` }, topLevelSellerScriptParamsOverride: { scoreAd: ` // scoreAd sees what's actually passed in. if (bid != 9) throw 'Wrong bid'; if (browserSignals.bidCurrency !== '???') throw 'Wrong currency';` } }); expectSuccess(config); createAndNavigateFencedFrame(test, config); await waitForObservedRequests(uuid, [ createSellerReportURL(uuid, 'top_9CAD'), createSellerReportURL(uuid, 'component_9???'), createBidderReportURL(uuid, '9???') ]); }, 'Multi-seller auction --- incomingBidInSellerCurrency does not go to top-level; component sellerCurrency does.'); 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.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinInterestGroup(test, uuid); await runBasicFledgeTestExpectingNoWinner(test, uuid, { decisionLogicURL: createDecisionScriptURL(uuid, { scoreAd: ` return {desirability: 2 * bid, incomingBidInSellerCurrency: 5* bid} ` }) }); }, 'Trying to use incomingBidInSellerCurrency w/o sellerCurrency set.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinInterestGroup(test, uuid); await runBasicFledgeTestExpectingWinner(test, uuid, { decisionLogicURL: createDecisionScriptURL(uuid, { scoreAd: ` return {desirability: 2 * bid, incomingBidInSellerCurrency: 5* bid} `, }), sellerCurrency: 'USD' }); }, 'Trying to use incomingBidInSellerCurrency w/sellerCurrency set.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinInterestGroup( test, uuid, {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); await runBasicFledgeTestExpectingNoWinner(test, uuid, { decisionLogicURL: createDecisionScriptURL(uuid, { scoreAd: ` return {desirability: 2 * bid, incomingBidInSellerCurrency: 5* bid} ` }), sellerCurrency: 'USD' }); }, 'Trying to use incomingBidInSellerCurrency to change bid already in that currency.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinInterestGroup( test, uuid, {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); await runBasicFledgeTestExpectingWinner(test, uuid, { decisionLogicURL: createDecisionScriptURL(uuid, { scoreAd: ` return {desirability: 2 * bid, incomingBidInSellerCurrency: bid} ` }), sellerCurrency: 'USD' }); }, 'incomingBidInSellerCurrency repeating value of bid already in that currency is OK.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinTwoGroupsForHighestScoringOther(test, uuid); await runBasicFledgeAuctionAndNavigate( test, uuid, {decisionLogicURL: createDecisionURLForHighestScoringOther(uuid)}); await waitForObservedRequests(uuid, [ createSellerReportURL(uuid, '10???_9???'), createBidderReportURL(uuid, '10???_9???'), // w/o sellerCurrency set, forDebuggingOnly reports original values and ??? // as tags. createSellerReportURL(uuid, 'dbg_10???_9???'), createBidderReportURL(uuid, 'dbg_10???_9???') ]); }, 'Converted currency use with no sellerCurrency set.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinTwoGroupsForHighestScoringOther(test, uuid); await runBasicFledgeAuctionAndNavigate(test, uuid, { decisionLogicURL: createDecisionURLForHighestScoringOther(uuid), sellerCurrency: 'USD' }); await waitForObservedRequests(uuid, [ createSellerReportURL(uuid, '10???_9USD'), createBidderReportURL(uuid, '10???_9USD'), // w/sellerCurrency set, forDebuggingOnly reports converted bids + // sellerCurrency. createSellerReportURL(uuid, 'dbg_10USD_9USD'), createBidderReportURL(uuid, 'dbg_10USD_9USD') ]); }, 'Converted currency use with sellerCurrency set matching.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinTwoGroupsForHighestScoringOther(test, uuid); await runBasicFledgeAuctionAndNavigate(test, uuid, { decisionLogicURL: createDecisionURLForHighestScoringOther(uuid), sellerCurrency: 'EUR' }); await waitForObservedRequests(uuid, [ createSellerReportURL(uuid, '10???_0EUR'), createBidderReportURL(uuid, '10???_0EUR'), // sellerCurrency set, and no bid available in it: get 0s. createSellerReportURL(uuid, 'dbg_0EUR_0EUR'), createBidderReportURL(uuid, 'dbg_0EUR_0EUR') ]); }, 'Converted currency use with sellerCurrency different, no conversion.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinTwoGroupsForHighestScoringOther(test, uuid); await runBasicFledgeAuctionAndNavigate(test, uuid, { decisionLogicURL: createDecisionURLForHighestScoringOther(uuid, 'converted = 3 * bid'), sellerCurrency: 'EUR' }); await waitForObservedRequests(uuid, [ createSellerReportURL(uuid, '10???_27EUR'), createBidderReportURL(uuid, '10???_27EUR'), // sellerCurrency set, converted bids. createSellerReportURL(uuid, 'dbg_30EUR_27EUR'), createBidderReportURL(uuid, 'dbg_30EUR_27EUR') ]); }, 'Converted currency use with sellerCurrency different, conversion.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinTwoGroupsForHighestScoringOther(test, uuid); let result = await runCurrencyComponentAuctionForHighestScoringOther(test, uuid, { componentConversion: ` modified = bid + 1; modifiedCurrency = 'EUR';`, componentAuctionConfigOverrides: {sellerCurrency: 'EUR'} }); expectSuccess(result); createAndNavigateFencedFrame(test, result); await waitForObservedRequests(uuid, [ createSellerReportURL(uuid, 'top_11EUR_0???'), createSellerReportURL(uuid, 'component_10???_0EUR'), createBidderReportURL(uuid, '10???_0EUR'), // forDebuggingOnly info w/sellerCurrency set relies on conversion; // but sellerCurrency is on component auction only. createBidderReportURL(uuid, 'dbg_0EUR_0EUR'), createSellerReportURL(uuid, 'dbg_component_0EUR_0EUR'), createSellerReportURL(uuid, 'dbg_top_11???_0???'), ]); }, 'Modified bid does not act in place of incomingBidInSellerCurrency.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinTwoGroupsForHighestScoringOther(test, uuid); let result = await runCurrencyComponentAuctionForHighestScoringOther(test, uuid, { componentConversion: ` modified = bid + 1; modifiedCurrency = 'EUR'; converted = bid - 1;`, componentAuctionConfigOverrides: {sellerCurrency: 'EUR'} }); expectSuccess(result); createAndNavigateFencedFrame(test, result); await waitForObservedRequests(uuid, [ createSellerReportURL(uuid, 'top_11EUR_0???'), createSellerReportURL(uuid, 'component_10???_8EUR'), createBidderReportURL(uuid, '10???_8EUR'), // Debug at component shows converted; top-level has no sellerCurrency, // so shows modified. createBidderReportURL(uuid, 'dbg_9EUR_8EUR'), createSellerReportURL(uuid, 'dbg_component_9EUR_8EUR'), createSellerReportURL(uuid, 'dbg_top_11???_0???'), ]); }, 'Both modified bid and incomingBidInSellerCurrency.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinTwoGroupsForHighestScoringOther(test, uuid); let result = await runCurrencyComponentAuctionForHighestScoringOther(test, uuid, { componentConversion: ` modified = bid + 1; modifiedCurrency = 'CAD';`, topLevelAuctionConfigOverrides: {sellerCurrency: 'EUR'}, topLevelConversion: `converted = 3 * bid;`, }); expectSuccess(result); createAndNavigateFencedFrame(test, result); await waitForObservedRequests(uuid, [ createSellerReportURL(uuid, 'top_11???_0???'), createSellerReportURL(uuid, 'component_10???_9???'), createBidderReportURL(uuid, '10???_9???'), // No sellerCurrency at component; debug at top-level shows the result of // conversion. createBidderReportURL(uuid, 'dbg_10???_9???'), createSellerReportURL(uuid, 'dbg_component_10???_9???'), createSellerReportURL(uuid, 'dbg_top_33EUR_0???'), ]); }, 'incomingBidInSellerCurrency at top-level trying to convert is OK.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinTwoGroupsForHighestScoringOther(test, uuid); let result = await runCurrencyComponentAuctionForHighestScoringOther(test, uuid, { componentConversion: ` modified = bid + 1; modifiedCurrency = 'EUR';`, topLevelAuctionConfigOverrides: {sellerCurrency: 'EUR'}, topLevelConversion: `converted = 3 * bid;`, }); // Tried to change a bid that was already in EUR. expectNoWinner(result); }, 'incomingBidInSellerCurrency at top-level trying to change bid is not OK.'); subsetTest(promise_test, async test => { const uuid = generateUuid(test); await joinTwoGroupsForHighestScoringOther(test, uuid); let result = await runCurrencyComponentAuctionForHighestScoringOther(test, uuid, { componentConversion: ` modified = bid + 1; modifiedCurrency = 'EUR';`, topLevelAuctionConfigOverrides: {sellerCurrency: 'EUR'}, topLevelConversion: `converted = bid;`, }); // Changing the bid to itself when it was already in right currency is OK. expectSuccess(result); createAndNavigateFencedFrame(test, result); await waitForObservedRequests(uuid, [ createSellerReportURL(uuid, 'top_11???_0???'), createSellerReportURL(uuid, 'component_10???_9???'), createBidderReportURL(uuid, '10???_9???'), // No sellerCurrency at component; debug at top-level shows the result of // no-op conversion. createBidderReportURL(uuid, 'dbg_10???_9???'), createSellerReportURL(uuid, 'dbg_component_10???_9???'), createSellerReportURL(uuid, 'dbg_top_11EUR_0???'), ]); }, 'incomingBidInSellerCurrency at top-level doing a no-op conversion OK.'); // TODO: PrivateAggregation. It follows the same rules as // highestScoringOtherBid, but is actually visible at top-level.