currency.https.window.js (34240B)
1 // META: script=/resources/testdriver.js 2 // META: script=/resources/testdriver-vendor.js 3 // META: script=/common/utils.js 4 // META: script=resources/fledge-util.sub.js 5 // META: script=/common/subset-tests.js 6 // META: timeout=long 7 // META: variant=?1-4 8 // META: variant=?5-8 9 // META: variant=?9-12 10 // META: variant=?13-16 11 // META: variant=?17-20 12 // META: variant=?21-24 13 // META: variant=?25-28 14 // META: variant=?29-32 15 // META: variant=?33-last 16 17 'use strict'; 18 19 const ORIGIN = window.location.origin; 20 21 // The tests in this file focus on calls to runAdAuction involving currency 22 // handling. 23 24 // Joins an interest group that bids 9USD on window.location.origin, and one 25 // that bids 10CAD on OTHER_ORIGIN1, each with a reportWin() report. 26 async function joinTwoCurrencyGroups(test, uuid) { 27 const reportWinURL = createBidderReportURL(uuid, 'USD'); 28 const biddingURL = createBiddingScriptURL( 29 {bidCurrency: 'USD', reportWin: `sendReportTo('${reportWinURL}')`}); 30 await joinInterestGroup(test, uuid, {biddingLogicURL: biddingURL}); 31 32 const otherReportWinURL = createBidderReportURL(uuid, 'CAD', OTHER_ORIGIN1); 33 const otherBiddingURL = createBiddingScriptURL({ 34 origin: OTHER_ORIGIN1, 35 bid: 10, 36 bidCurrency: 'CAD', 37 reportWin: `sendReportTo('${otherReportWinURL}')` 38 }); 39 await joinCrossOriginInterestGroup( 40 test, uuid, OTHER_ORIGIN1, {biddingLogicURL: otherBiddingURL}); 41 } 42 43 function createBiddingScriptURLWithCurrency(uuid, currency) { 44 return createBiddingScriptURL({ 45 bidCurrency: currency, 46 allowComponentAuction: true, 47 reportWin: ` 48 sendReportTo('${createBidderReportURL(uuid, /*id=*/ '')}' + 49 browserSignals.bid + browserSignals.bidCurrency);`, 50 }); 51 } 52 53 // Creates a component-auction eligible bidding script returning a bid `bid` in 54 // currency `currency`. It provides a reporting handler that logs bid and 55 // highestScoringOtherBid along with their currencies. 56 function createBiddingScriptURLForHighestScoringOther(uuid, bid, currency) { 57 return createBiddingScriptURL({ 58 bid: bid, 59 bidCurrency: currency, 60 allowComponentAuction: true, 61 generateBid: ` 62 forDebuggingOnly.reportAdAuctionWin( 63 '${createBidderReportURL(uuid, /*id=*/ 'dbg_')}' + 64 '\${winningBid}\${winningBidCurrency}_' + 65 '\${highestScoringOtherBid}\${highestScoringOtherBidCurrency}');`, 66 reportWin: ` 67 sendReportTo( 68 '${createBidderReportURL(uuid, /*id=*/ '')}' + 69 browserSignals.bid + browserSignals.bidCurrency + 70 '_' + browserSignals.highestScoringOtherBid + 71 browserSignals.highestScoringOtherBidCurrency);`, 72 }); 73 } 74 75 function createDecisionURLExpectCurrency(uuid, currencyInScore) { 76 return createDecisionScriptURL(uuid, { 77 scoreAd: ` 78 if (browserSignals.bidCurrency !== '${currencyInScore}') 79 throw 'Wrong currency';`, 80 reportResult: ` 81 sendReportTo('${createSellerReportURL(uuid, /*id=*/ '')}' + 82 browserSignals.bid + browserSignals.bidCurrency);`, 83 }); 84 } 85 86 // Creates a component-auction seller script, which by default just scores 87 // bid * 2, but the `conversion` argument can be used to customize bid 88 // modification and currenct conversion. 89 // 90 // The script provides a reporting handler that logs bid and 91 // highestScoringOtherBid along with their currencies as well as `suffix`. 92 function createDecisionURLForHighestScoringOther( 93 uuid, conversion = '', suffix = '') { 94 return createDecisionScriptURL(uuid, { 95 scoreAd: ` 96 forDebuggingOnly.reportAdAuctionWin( 97 '${createSellerReportURL(uuid, /*id=*/ 'dbg_')}' + '${suffix}' + 98 '\${winningBid}\${winningBidCurrency}_' + 99 '\${highestScoringOtherBid}\${highestScoringOtherBidCurrency}'); 100 let converted = undefined; 101 let modified = undefined; 102 let modifiedCurrency = undefined; 103 ${conversion} 104 return {desirability: 2 * bid, 105 incomingBidInSellerCurrency: converted, 106 bid: modified, 107 bidCurrency: modifiedCurrency, 108 allowComponentAuction: true}; 109 `, 110 reportResult: ` 111 sendReportTo( 112 '${createSellerReportURL(uuid, /*id=*/ '')}' + '${suffix}' + 113 browserSignals.bid + browserSignals.bidCurrency + 114 '_' + browserSignals.highestScoringOtherBid + 115 browserSignals.highestScoringOtherBidCurrency);`, 116 }); 117 } 118 119 // Joins groups for 9USD and 10USD, with reporting including 120 // highestScoringOtherBid. 121 async function joinTwoGroupsForHighestScoringOther(test, uuid) { 122 await joinInterestGroup(test, uuid, { 123 name: 'group-9USD', 124 biddingLogicURL: 125 createBiddingScriptURLForHighestScoringOther(uuid, /*bid=*/ 9, 'USD') 126 }); 127 await joinInterestGroup(test, uuid, { 128 name: 'group-10USD', 129 biddingLogicURL: 130 createBiddingScriptURLForHighestScoringOther(uuid, /*bid=*/ 10, 'USD') 131 }); 132 } 133 134 async function runCurrencyComponentAuction(test, uuid, params = {}) { 135 let auctionConfigOverrides = { 136 interestGroupBuyers: [], 137 decisionLogicURL: createDecisionScriptURL(uuid, { 138 reportResult: ` 139 sendReportTo('${createSellerReportURL(uuid, 'top_')}' + 140 browserSignals.bid + browserSignals.bidCurrency)`, 141 ...params.topLevelSellerScriptParamsOverride 142 }), 143 componentAuctions: [{ 144 seller: ORIGIN, 145 decisionLogicURL: createDecisionScriptURL(uuid, { 146 reportResult: ` 147 sendReportTo('${createSellerReportURL(uuid, 'component_')}' + 148 browserSignals.bid + browserSignals.bidCurrency)`, 149 ...params.componentSellerScriptParamsOverride 150 }), 151 interestGroupBuyers: [ORIGIN], 152 ...params.componentAuctionConfigOverrides 153 }], 154 ...params.topLevelAuctionConfigOverrides 155 }; 156 return await runBasicFledgeAuction(test, uuid, auctionConfigOverrides); 157 } 158 159 // Runs a component auction with reporting scripts that report bid and 160 // highestScoringOtherBid, along with their currencies. 161 // 162 // Customization points in `params` are: 163 // componentAuctionConfigOverrides, topLevelAuctionConfigOverrides: 164 // edit auctionConfig for given auction level. 165 // 166 // topLevelConversion and componentConversion: 167 // Permit customizing how the scoring function does currency conversiona and 168 // bid modification. See createDecisionURLForHighestScoringOther(). 169 async function runCurrencyComponentAuctionForHighestScoringOther( 170 test, uuid, params = {}) { 171 let auctionConfigOverrides = { 172 interestGroupBuyers: [], 173 decisionLogicURL: createDecisionURLForHighestScoringOther( 174 uuid, params.topLevelConversion || '', 'top_'), 175 componentAuctions: [{ 176 seller: ORIGIN, 177 decisionLogicURL: createDecisionURLForHighestScoringOther( 178 uuid, params.componentConversion || '', 'component_'), 179 interestGroupBuyers: [ORIGIN], 180 ...params.componentAuctionConfigOverrides 181 }], 182 ...params.topLevelAuctionConfigOverrides 183 }; 184 return await runBasicFledgeAuction(test, uuid, auctionConfigOverrides); 185 } 186 187 subsetTest(promise_test, async test => { 188 const uuid = generateUuid(test); 189 await joinInterestGroup( 190 test, uuid, 191 {biddingLogicURL: createBiddingScriptURL({bidCurrency: 'usd'})}); 192 await runBasicFledgeTestExpectingNoWinner(test, uuid); 193 }, 'Returning bid with invalid currency.'); 194 195 subsetTest(promise_test, async test => { 196 const uuid = generateUuid(test); 197 await joinInterestGroup( 198 test, uuid, 199 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 200 await runBasicFledgeAuctionAndNavigate( 201 test, uuid, 202 {decisionLogicURL: createDecisionURLExpectCurrency(uuid, 'USD')}); 203 await waitForObservedRequests(uuid, [ 204 createSellerReportURL(uuid, '9???'), createBidderReportURL(uuid, '9???') 205 ]); 206 }, 'Returning bid with currency, configuration w/o currency.'); 207 208 subsetTest(promise_test, async test => { 209 const uuid = generateUuid(test); 210 await joinInterestGroup( 211 test, uuid, 212 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, undefined)}); 213 await runBasicFledgeAuctionAndNavigate(test, uuid, { 214 perBuyerCurrencies: {'*': 'USD'}, 215 decisionLogicURL: createDecisionURLExpectCurrency(uuid, '???') 216 }); 217 await waitForObservedRequests(uuid, [ 218 createSellerReportURL(uuid, '9USD'), createBidderReportURL(uuid, '9USD') 219 ]); 220 }, 'Returning bid w/o currency, configuration w/currency.'); 221 222 subsetTest(promise_test, async test => { 223 const uuid = generateUuid(test); 224 await joinInterestGroup( 225 test, uuid, 226 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 227 await runBasicFledgeAuctionAndNavigate(test, uuid, { 228 perBuyerCurrencies: {'*': 'USD'}, 229 decisionLogicURL: createDecisionURLExpectCurrency(uuid, 'USD') 230 }); 231 await waitForObservedRequests(uuid, [ 232 createSellerReportURL(uuid, '9USD'), createBidderReportURL(uuid, '9USD') 233 ]); 234 }, 'Returning bid w/currency, configuration w/matching currency.'); 235 236 subsetTest(promise_test, async test => { 237 const uuid = generateUuid(test); 238 await joinInterestGroup( 239 test, uuid, 240 {biddingLogicURL: createBiddingScriptURL({bidCurrency: 'USD'})}); 241 await runBasicFledgeTestExpectingNoWinner( 242 test, uuid, {perBuyerCurrencies: {'*': 'CAD'}}); 243 }, 'Returning bid w/currency, configuration w/different currency.'); 244 245 subsetTest(promise_test, async test => { 246 const uuid = generateUuid(test); 247 await joinTwoCurrencyGroups(test, uuid); 248 let auctionConfigOverrides = { 249 interestGroupBuyers: [ORIGIN, OTHER_ORIGIN1], 250 perBuyerCurrencies: {} 251 }; 252 auctionConfigOverrides.perBuyerCurrencies['*'] = 'USD'; 253 auctionConfigOverrides.perBuyerCurrencies[OTHER_ORIGIN1] = 'CAD'; 254 await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfigOverrides); 255 256 // Since the scoring script doesn't actually look at the currencies, 257 // We expect 10CAD to win because 10 > 9 258 await waitForObservedRequests(uuid, [ 259 createBidderReportURL(uuid, 'CAD', OTHER_ORIGIN1), 260 createSellerReportURL(uuid) 261 ]); 262 }, 'Different currencies for different origins, all match.'); 263 264 subsetTest(promise_test, async test => { 265 const uuid = generateUuid(test); 266 await joinTwoCurrencyGroups(test, uuid); 267 let auctionConfigOverrides = { 268 interestGroupBuyers: [ORIGIN, OTHER_ORIGIN1], 269 perBuyerCurrencies: {} 270 }; 271 auctionConfigOverrides.perBuyerCurrencies[ORIGIN] = 'USD'; 272 auctionConfigOverrides.perBuyerCurrencies[OTHER_ORIGIN1] = 'EUR'; 273 await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfigOverrides); 274 275 // Since the configuration for CAD script expects EUR only the USD bid goes 276 // through. 277 await waitForObservedRequests( 278 uuid, [createBidderReportURL(uuid, 'USD'), createSellerReportURL(uuid)]); 279 }, 'Different currencies for different origins, USD one matches.'); 280 281 subsetTest(promise_test, async test => { 282 const uuid = generateUuid(test); 283 await joinTwoCurrencyGroups(test, uuid); 284 let auctionConfigOverrides = { 285 interestGroupBuyers: [ORIGIN, OTHER_ORIGIN1], 286 perBuyerCurrencies: {} 287 }; 288 auctionConfigOverrides.perBuyerCurrencies['*'] = 'EUR'; 289 }, 'Different currencies for different origins, none match.'); 290 291 subsetTest(promise_test, async test => { 292 const uuid = generateUuid(test); 293 await joinInterestGroup( 294 test, uuid, 295 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 296 let config = await runCurrencyComponentAuction(test, uuid, { 297 topLevelSellerScriptParamsOverride: { 298 scoreAd: ` 299 if (browserSignals.bidCurrency !== 'USD') 300 throw 'Wrong currency';` 301 } 302 }); 303 expectSuccess(config); 304 createAndNavigateFencedFrame(test, config); 305 // While scoring sees the original currency tag, reporting currency tags are 306 // config-based. 307 await waitForObservedRequests(uuid, [ 308 createSellerReportURL(uuid, 'top_9???'), 309 createSellerReportURL(uuid, 'component_9???'), 310 createBidderReportURL(uuid, '9???') 311 ]); 312 }, 'Multi-seller auction --- no currency restriction.'); 313 314 315 subsetTest(promise_test, async test => { 316 const uuid = generateUuid(test); 317 await joinInterestGroup( 318 test, uuid, 319 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 320 let config = await runCurrencyComponentAuction(test, uuid, { 321 componentAuctionConfigOverrides: {sellerCurrency: 'USD'}, 322 topLevelSellerScriptParamsOverride: { 323 scoreAd: ` 324 if (browserSignals.bidCurrency !== 'USD') 325 throw 'Wrong currency';` 326 } 327 }); 328 expectSuccess(config); 329 createAndNavigateFencedFrame(test, config); 330 // Because component's sellerCurrency is USD, the bid it makes is seen to be 331 // in dollars by top-level reporting. That doesn't affect reporting in its 332 // own auction. 333 await waitForObservedRequests(uuid, [ 334 createSellerReportURL(uuid, 'top_9USD'), 335 createSellerReportURL(uuid, 'component_9???'), 336 createBidderReportURL(uuid, '9???') 337 ]); 338 }, 'Multi-seller auction --- component sellerCurrency matches bid.'); 339 340 subsetTest(promise_test, async test => { 341 const uuid = generateUuid(test); 342 await joinInterestGroup( 343 test, uuid, 344 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 345 let config = await runCurrencyComponentAuction(test, uuid, { 346 componentAuctionConfigOverrides: {sellerCurrency: 'EUR'}, 347 componentSellerScriptParamsOverride: { 348 scoreAd: ` 349 return {desirability: 2 * bid, allowComponentAuction: true, 350 bid: 1.5 * bid, bidCurrency: 'EUR'} 351 ` 352 }, 353 topLevelSellerScriptParamsOverride: { 354 scoreAd: ` 355 if (browserSignals.bidCurrency !== 'EUR') 356 throw 'Wrong currency';` 357 } 358 }); 359 expectSuccess(config); 360 createAndNavigateFencedFrame(test, config); 361 // Because component's sellerCurrency is USD, the bid it makes is seen to be 362 // in dollars by top-level reporting. That doesn't affect reporting in its 363 // own auction. 364 await waitForObservedRequests(uuid, [ 365 createSellerReportURL(uuid, 'top_13.5EUR'), 366 createSellerReportURL(uuid, 'component_9???'), 367 createBidderReportURL(uuid, '9???') 368 ]); 369 }, 'Multi-seller auction --- component scoreAd modifies bid into its sellerCurrency.'); 370 371 subsetTest(promise_test, async test => { 372 const uuid = generateUuid(test); 373 await joinInterestGroup( 374 test, uuid, 375 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 376 let config = await runCurrencyComponentAuction(test, uuid, { 377 componentAuctionConfigOverrides: {sellerCurrency: 'EUR'}, 378 componentSellerScriptParamsOverride: { 379 scoreAd: ` 380 return {desirability: 2 * bid, allowComponentAuction: true, 381 bid: 1.5 * bid} 382 ` 383 }, 384 topLevelSellerScriptParamsOverride: { 385 scoreAd: ` 386 // scoreAd sees what's actually passed in. 387 if (browserSignals.bidCurrency !== '???') 388 throw 'Wrong currency';` 389 } 390 }); 391 expectSuccess(config); 392 createAndNavigateFencedFrame(test, config); 393 await waitForObservedRequests(uuid, [ 394 createSellerReportURL(uuid, 'top_13.5EUR'), 395 createSellerReportURL(uuid, 'component_9???'), 396 createBidderReportURL(uuid, '9???') 397 ]); 398 }, 'Multi-seller auction --- component scoreAd modifies bid, no explicit currency.'); 399 400 subsetTest(promise_test, async test => { 401 const uuid = generateUuid(test); 402 await joinInterestGroup( 403 test, uuid, 404 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 405 let config = await runCurrencyComponentAuction(test, uuid, { 406 componentAuctionConfigOverrides: 407 {sellerCurrency: 'EUR', perBuyerCurrencies: {'*': 'USD'}}, 408 componentSellerScriptParamsOverride: { 409 scoreAd: ` 410 return {desirability: 2 * bid, allowComponentAuction: true, 411 bid: 1.5 * bid} 412 ` 413 }, 414 topLevelSellerScriptParamsOverride: { 415 scoreAd: ` 416 // scoreAd sees what's actually passed in. 417 if (browserSignals.bidCurrency !== '???') 418 throw 'Wrong currency';` 419 } 420 }); 421 expectSuccess(config); 422 createAndNavigateFencedFrame(test, config); 423 await waitForObservedRequests(uuid, [ 424 createSellerReportURL(uuid, 'top_13.5EUR'), 425 createSellerReportURL(uuid, 'component_9USD'), 426 createBidderReportURL(uuid, '9USD') 427 ]); 428 }, 'Multi-seller auction --- component scoreAd modifies bid, bidder has bidCurrency.'); 429 430 subsetTest(promise_test, async test => { 431 const uuid = generateUuid(test); 432 await joinInterestGroup( 433 test, uuid, 434 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 435 let config = await runCurrencyComponentAuction(test, uuid, { 436 componentAuctionConfigOverrides: {perBuyerCurrencies: {'*': 'USD'}}, 437 componentSellerScriptParamsOverride: { 438 scoreAd: ` 439 return {desirability: 2 * bid, allowComponentAuction: true, 440 bid: 1.5 * bid} 441 ` 442 }, 443 topLevelSellerScriptParamsOverride: { 444 scoreAd: ` 445 // scoreAd sees what's actually passed in. 446 if (browserSignals.bidCurrency !== '???') 447 throw 'Wrong currency';` 448 } 449 }); 450 expectSuccess(config); 451 createAndNavigateFencedFrame(test, config); 452 await waitForObservedRequests(uuid, [ 453 createSellerReportURL(uuid, 'top_13.5???'), 454 createSellerReportURL(uuid, 'component_9USD'), 455 createBidderReportURL(uuid, '9USD') 456 ]); 457 }, 'Multi-seller auction --- only bidder currency specified.'); 458 459 subsetTest(promise_test, async test => { 460 const uuid = generateUuid(test); 461 await joinInterestGroup( 462 test, uuid, 463 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 464 let config = await runCurrencyComponentAuction(test, uuid, { 465 componentAuctionConfigOverrides: {perBuyerCurrencies: {'*': 'USD'}}, 466 componentSellerScriptParamsOverride: { 467 scoreAd: ` 468 return {desirability: 2 * bid, allowComponentAuction: true, 469 bid: 1.5 * bid, bidCurrency: 'CAD'} 470 ` 471 }, 472 topLevelSellerScriptParamsOverride: { 473 scoreAd: ` 474 // scoreAd sees what's actually passed in. 475 if (browserSignals.bidCurrency !== 'CAD') 476 throw 'Wrong currency';` 477 } 478 }); 479 expectSuccess(config); 480 createAndNavigateFencedFrame(test, config); 481 await waitForObservedRequests(uuid, [ 482 createSellerReportURL(uuid, 'top_13.5???'), 483 createSellerReportURL(uuid, 'component_9USD'), 484 createBidderReportURL(uuid, '9USD') 485 ]); 486 }, 'Multi-seller auction --- only bidder currency in config, component uses explicit currency.'); 487 488 subsetTest(promise_test, async test => { 489 const uuid = generateUuid(test); 490 await joinInterestGroup(test, uuid, { 491 biddingLogicURL: 492 createBiddingScriptURLWithCurrency(uuid, /*bidCurrency=*/ undefined) 493 }); 494 let config = await runCurrencyComponentAuction(test, uuid, { 495 componentAuctionConfigOverrides: {sellerCurrency: 'CAD'}, 496 componentSellerScriptParamsOverride: { 497 scoreAd: ` 498 return {desirability: 2 * bid, allowComponentAuction: true, 499 incomingBidInSellerCurrency: 12345} 500 ` 501 }, 502 topLevelSellerScriptParamsOverride: { 503 scoreAd: ` 504 // scoreAd sees what's actually passed in. 505 if (bid !== 9) 506 throw 'Wrong bid'; 507 if (browserSignals.bidCurrency !== '???') 508 throw 'Wrong currency';` 509 } 510 }); 511 expectSuccess(config); 512 createAndNavigateFencedFrame(test, config); 513 await waitForObservedRequests(uuid, [ 514 createSellerReportURL(uuid, 'top_9CAD'), 515 createSellerReportURL(uuid, 'component_9???'), 516 createBidderReportURL(uuid, '9???') 517 ]); 518 }, 'Multi-seller auction --- incomingBidInSellerCurrency does not go to top-level; component sellerCurrency does.'); 519 520 subsetTest(promise_test, async test => { 521 const uuid = generateUuid(test); 522 await joinInterestGroup( 523 test, uuid, 524 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 525 let result = await runCurrencyComponentAuction(test, uuid, { 526 componentAuctionConfigOverrides: {sellerCurrency: 'EUR'}, 527 componentSellerScriptParamsOverride: { 528 scoreAd: ` 529 return {desirability: 2 * bid, allowComponentAuction: true, 530 bid: 1.5 * bid, bidCurrency: 'CAD'} 531 ` 532 } 533 }); 534 expectNoWinner(result); 535 }, 'Multi-seller auction --- component scoreAd modifies bid to wrong currency.'); 536 537 subsetTest(promise_test, async test => { 538 const uuid = generateUuid(test); 539 await joinInterestGroup( 540 test, uuid, 541 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 542 let topLevelConfigOverride = {perBuyerCurrencies: {}}; 543 topLevelConfigOverride.perBuyerCurrencies[ORIGIN] = 'USD'; 544 let config = await runCurrencyComponentAuction(test, uuid, { 545 topLevelAuctionConfigOverrides: topLevelConfigOverride, 546 topLevelSellerScriptParamsOverride: { 547 scoreAd: ` 548 if (browserSignals.bidCurrency !== 'USD') 549 throw 'Wrong currency';` 550 } 551 }); 552 expectSuccess(config); 553 createAndNavigateFencedFrame(test, config); 554 // Because component is constrained by perBuyerCurrencies for it on top-level 555 // to USD, the bid it makes is seen to be in dollars by top-level reporting. 556 // That doesn't affect reporting in its own auction. 557 await waitForObservedRequests(uuid, [ 558 createSellerReportURL(uuid, 'top_9USD'), 559 createSellerReportURL(uuid, 'component_9???'), 560 createBidderReportURL(uuid, '9???') 561 ]); 562 }, 'Multi-seller auction --- top-level perBuyerCurrencies matches bid.'); 563 564 subsetTest(promise_test, async test => { 565 const uuid = generateUuid(test); 566 await joinInterestGroup( 567 test, uuid, 568 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 569 let topLevelConfigOverride = {perBuyerCurrencies: {}}; 570 topLevelConfigOverride.perBuyerCurrencies[ORIGIN] = 'USD'; 571 let config = await runCurrencyComponentAuction(test, uuid, { 572 componentAuctionConfigOverrides: {sellerCurrency: 'USD'}, 573 topLevelAuctionConfigOverrides: topLevelConfigOverride, 574 topLevelSellerScriptParamsOverride: { 575 scoreAd: ` 576 if (browserSignals.bidCurrency !== 'USD') 577 throw 'Wrong currency';` 578 } 579 }); 580 expectSuccess(config); 581 createAndNavigateFencedFrame(test, config); 582 // Because component is constrained by perBuyerCurrencies for it on top-level 583 // to USD, the bid it makes is seen to be in dollars by top-level reporting. 584 // That doesn't affect reporting in its own auction. 585 await waitForObservedRequests(uuid, [ 586 createSellerReportURL(uuid, 'top_9USD'), 587 createSellerReportURL(uuid, 'component_9???'), 588 createBidderReportURL(uuid, '9???') 589 ]); 590 }, 'Multi-seller auction --- consistent sellerConfig and top-level perBuyerCurrencies.'); 591 592 subsetTest(promise_test, async test => { 593 const uuid = generateUuid(test); 594 await joinInterestGroup( 595 test, uuid, 596 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 597 let topLevelConfigOverride = {perBuyerCurrencies: {}}; 598 topLevelConfigOverride.perBuyerCurrencies[ORIGIN] = 'EUR'; 599 let result = await runCurrencyComponentAuction(test, uuid, { 600 componentAuctionConfigOverrides: {sellerCurrency: 'USD'}, 601 topLevelAuctionConfigOverrides: topLevelConfigOverride, 602 topLevelSellerScriptParamsOverride: { 603 scoreAd: ` 604 if (browserSignals.bidCurrency !== 'USD') 605 throw 'Wrong currency';` 606 } 607 }); 608 expectNoWinner(result); 609 }, 'Multi-seller auction --- inconsistent sellerConfig and top-level perBuyerCurrencies.'); 610 611 subsetTest(promise_test, async test => { 612 const uuid = generateUuid(test); 613 await joinInterestGroup( 614 test, uuid, 615 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 616 let topLevelConfigOverride = {perBuyerCurrencies: {}}; 617 topLevelConfigOverride.perBuyerCurrencies[ORIGIN] = 'EUR'; 618 619 let result = await runCurrencyComponentAuction( 620 test, uuid, {componentAuctionConfigOverrides: topLevelConfigOverride}); 621 expectNoWinner(result); 622 }, 'Multi-seller auction --- top-level perBuyerCurrencies different from bid.'); 623 624 subsetTest(promise_test, async test => { 625 const uuid = generateUuid(test); 626 await joinInterestGroup( 627 test, uuid, 628 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 629 let result = await runCurrencyComponentAuction( 630 test, uuid, {componentAuctionConfigOverrides: {sellerCurrency: 'EUR'}}); 631 expectNoWinner(result); 632 }, 'Multi-seller auction --- component sellerCurrency different from bid.'); 633 634 subsetTest(promise_test, async test => { 635 const uuid = generateUuid(test); 636 await joinInterestGroup(test, uuid); 637 await runBasicFledgeTestExpectingNoWinner(test, uuid, { 638 decisionLogicURL: createDecisionScriptURL(uuid, { 639 scoreAd: ` 640 return {desirability: 2 * bid, 641 incomingBidInSellerCurrency: 5* bid} 642 ` 643 }) 644 }); 645 }, 'Trying to use incomingBidInSellerCurrency w/o sellerCurrency set.'); 646 647 subsetTest(promise_test, async test => { 648 const uuid = generateUuid(test); 649 await joinInterestGroup(test, uuid); 650 await runBasicFledgeTestExpectingWinner(test, uuid, { 651 decisionLogicURL: createDecisionScriptURL(uuid, { 652 scoreAd: ` 653 return {desirability: 2 * bid, 654 incomingBidInSellerCurrency: 5* bid} 655 `, 656 }), 657 sellerCurrency: 'USD' 658 }); 659 }, 'Trying to use incomingBidInSellerCurrency w/sellerCurrency set.'); 660 661 subsetTest(promise_test, async test => { 662 const uuid = generateUuid(test); 663 await joinInterestGroup( 664 test, uuid, 665 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 666 await runBasicFledgeTestExpectingNoWinner(test, uuid, { 667 decisionLogicURL: createDecisionScriptURL(uuid, { 668 scoreAd: ` 669 return {desirability: 2 * bid, 670 incomingBidInSellerCurrency: 5* bid} 671 ` 672 }), 673 sellerCurrency: 'USD' 674 }); 675 }, 'Trying to use incomingBidInSellerCurrency to change bid already in that currency.'); 676 677 subsetTest(promise_test, async test => { 678 const uuid = generateUuid(test); 679 await joinInterestGroup( 680 test, uuid, 681 {biddingLogicURL: createBiddingScriptURLWithCurrency(uuid, 'USD')}); 682 await runBasicFledgeTestExpectingWinner(test, uuid, { 683 decisionLogicURL: createDecisionScriptURL(uuid, { 684 scoreAd: ` 685 return {desirability: 2 * bid, 686 incomingBidInSellerCurrency: bid} 687 ` 688 }), 689 sellerCurrency: 'USD' 690 }); 691 }, 'incomingBidInSellerCurrency repeating value of bid already in that currency is OK.'); 692 693 subsetTest(promise_test, async test => { 694 const uuid = generateUuid(test); 695 await joinTwoGroupsForHighestScoringOther(test, uuid); 696 await runBasicFledgeAuctionAndNavigate( 697 test, uuid, 698 {decisionLogicURL: createDecisionURLForHighestScoringOther(uuid)}); 699 await waitForObservedRequests(uuid, [ 700 createSellerReportURL(uuid, '10???_9???'), 701 createBidderReportURL(uuid, '10???_9???'), 702 // w/o sellerCurrency set, forDebuggingOnly reports original values and ??? 703 // as tags. 704 createSellerReportURL(uuid, 'dbg_10???_9???'), 705 createBidderReportURL(uuid, 'dbg_10???_9???') 706 ]); 707 }, 'Converted currency use with no sellerCurrency set.'); 708 709 subsetTest(promise_test, async test => { 710 const uuid = generateUuid(test); 711 await joinTwoGroupsForHighestScoringOther(test, uuid); 712 await runBasicFledgeAuctionAndNavigate(test, uuid, { 713 decisionLogicURL: createDecisionURLForHighestScoringOther(uuid), 714 sellerCurrency: 'USD' 715 }); 716 await waitForObservedRequests(uuid, [ 717 createSellerReportURL(uuid, '10???_9USD'), 718 createBidderReportURL(uuid, '10???_9USD'), 719 // w/sellerCurrency set, forDebuggingOnly reports converted bids + 720 // sellerCurrency. 721 createSellerReportURL(uuid, 'dbg_10USD_9USD'), 722 createBidderReportURL(uuid, 'dbg_10USD_9USD') 723 ]); 724 }, 'Converted currency use with sellerCurrency set matching.'); 725 726 subsetTest(promise_test, async test => { 727 const uuid = generateUuid(test); 728 await joinTwoGroupsForHighestScoringOther(test, uuid); 729 await runBasicFledgeAuctionAndNavigate(test, uuid, { 730 decisionLogicURL: createDecisionURLForHighestScoringOther(uuid), 731 sellerCurrency: 'EUR' 732 }); 733 await waitForObservedRequests(uuid, [ 734 createSellerReportURL(uuid, '10???_0EUR'), 735 createBidderReportURL(uuid, '10???_0EUR'), 736 // sellerCurrency set, and no bid available in it: get 0s. 737 createSellerReportURL(uuid, 'dbg_0EUR_0EUR'), 738 createBidderReportURL(uuid, 'dbg_0EUR_0EUR') 739 ]); 740 }, 'Converted currency use with sellerCurrency different, no conversion.'); 741 742 subsetTest(promise_test, async test => { 743 const uuid = generateUuid(test); 744 await joinTwoGroupsForHighestScoringOther(test, uuid); 745 await runBasicFledgeAuctionAndNavigate(test, uuid, { 746 decisionLogicURL: 747 createDecisionURLForHighestScoringOther(uuid, 'converted = 3 * bid'), 748 sellerCurrency: 'EUR' 749 }); 750 await waitForObservedRequests(uuid, [ 751 createSellerReportURL(uuid, '10???_27EUR'), 752 createBidderReportURL(uuid, '10???_27EUR'), 753 // sellerCurrency set, converted bids. 754 createSellerReportURL(uuid, 'dbg_30EUR_27EUR'), 755 createBidderReportURL(uuid, 'dbg_30EUR_27EUR') 756 ]); 757 }, 'Converted currency use with sellerCurrency different, conversion.'); 758 759 subsetTest(promise_test, async test => { 760 const uuid = generateUuid(test); 761 await joinTwoGroupsForHighestScoringOther(test, uuid); 762 let result = 763 await runCurrencyComponentAuctionForHighestScoringOther(test, uuid, { 764 componentConversion: ` 765 modified = bid + 1; 766 modifiedCurrency = 'EUR';`, 767 componentAuctionConfigOverrides: {sellerCurrency: 'EUR'} 768 }); 769 expectSuccess(result); 770 createAndNavigateFencedFrame(test, result); 771 await waitForObservedRequests(uuid, [ 772 createSellerReportURL(uuid, 'top_11EUR_0???'), 773 createSellerReportURL(uuid, 'component_10???_0EUR'), 774 createBidderReportURL(uuid, '10???_0EUR'), 775 // forDebuggingOnly info w/sellerCurrency set relies on conversion; 776 // but sellerCurrency is on component auction only. 777 createBidderReportURL(uuid, 'dbg_0EUR_0EUR'), 778 createSellerReportURL(uuid, 'dbg_component_0EUR_0EUR'), 779 createSellerReportURL(uuid, 'dbg_top_11???_0???'), 780 ]); 781 }, 'Modified bid does not act in place of incomingBidInSellerCurrency.'); 782 783 subsetTest(promise_test, async test => { 784 const uuid = generateUuid(test); 785 await joinTwoGroupsForHighestScoringOther(test, uuid); 786 let result = 787 await runCurrencyComponentAuctionForHighestScoringOther(test, uuid, { 788 componentConversion: ` 789 modified = bid + 1; 790 modifiedCurrency = 'EUR'; 791 converted = bid - 1;`, 792 componentAuctionConfigOverrides: {sellerCurrency: 'EUR'} 793 }); 794 expectSuccess(result); 795 createAndNavigateFencedFrame(test, result); 796 await waitForObservedRequests(uuid, [ 797 createSellerReportURL(uuid, 'top_11EUR_0???'), 798 createSellerReportURL(uuid, 'component_10???_8EUR'), 799 createBidderReportURL(uuid, '10???_8EUR'), 800 // Debug at component shows converted; top-level has no sellerCurrency, 801 // so shows modified. 802 createBidderReportURL(uuid, 'dbg_9EUR_8EUR'), 803 createSellerReportURL(uuid, 'dbg_component_9EUR_8EUR'), 804 createSellerReportURL(uuid, 'dbg_top_11???_0???'), 805 ]); 806 }, 'Both modified bid and incomingBidInSellerCurrency.'); 807 808 subsetTest(promise_test, async test => { 809 const uuid = generateUuid(test); 810 await joinTwoGroupsForHighestScoringOther(test, uuid); 811 let result = 812 await runCurrencyComponentAuctionForHighestScoringOther(test, uuid, { 813 componentConversion: ` 814 modified = bid + 1; 815 modifiedCurrency = 'CAD';`, 816 topLevelAuctionConfigOverrides: {sellerCurrency: 'EUR'}, 817 topLevelConversion: `converted = 3 * bid;`, 818 }); 819 expectSuccess(result); 820 createAndNavigateFencedFrame(test, result); 821 await waitForObservedRequests(uuid, [ 822 createSellerReportURL(uuid, 'top_11???_0???'), 823 createSellerReportURL(uuid, 'component_10???_9???'), 824 createBidderReportURL(uuid, '10???_9???'), 825 // No sellerCurrency at component; debug at top-level shows the result of 826 // conversion. 827 createBidderReportURL(uuid, 'dbg_10???_9???'), 828 createSellerReportURL(uuid, 'dbg_component_10???_9???'), 829 createSellerReportURL(uuid, 'dbg_top_33EUR_0???'), 830 ]); 831 }, 'incomingBidInSellerCurrency at top-level trying to convert is OK.'); 832 833 subsetTest(promise_test, async test => { 834 const uuid = generateUuid(test); 835 await joinTwoGroupsForHighestScoringOther(test, uuid); 836 let result = 837 await runCurrencyComponentAuctionForHighestScoringOther(test, uuid, { 838 componentConversion: ` 839 modified = bid + 1; 840 modifiedCurrency = 'EUR';`, 841 topLevelAuctionConfigOverrides: {sellerCurrency: 'EUR'}, 842 topLevelConversion: `converted = 3 * bid;`, 843 }); 844 // Tried to change a bid that was already in EUR. 845 expectNoWinner(result); 846 }, 'incomingBidInSellerCurrency at top-level trying to change bid is not OK.'); 847 848 subsetTest(promise_test, async test => { 849 const uuid = generateUuid(test); 850 await joinTwoGroupsForHighestScoringOther(test, uuid); 851 let result = 852 await runCurrencyComponentAuctionForHighestScoringOther(test, uuid, { 853 componentConversion: ` 854 modified = bid + 1; 855 modifiedCurrency = 'EUR';`, 856 topLevelAuctionConfigOverrides: {sellerCurrency: 'EUR'}, 857 topLevelConversion: `converted = bid;`, 858 }); 859 // Changing the bid to itself when it was already in right currency is OK. 860 expectSuccess(result); 861 createAndNavigateFencedFrame(test, result); 862 await waitForObservedRequests(uuid, [ 863 createSellerReportURL(uuid, 'top_11???_0???'), 864 createSellerReportURL(uuid, 'component_10???_9???'), 865 createBidderReportURL(uuid, '10???_9???'), 866 // No sellerCurrency at component; debug at top-level shows the result of 867 // no-op conversion. 868 createBidderReportURL(uuid, 'dbg_10???_9???'), 869 createSellerReportURL(uuid, 'dbg_component_10???_9???'), 870 createSellerReportURL(uuid, 'dbg_top_11EUR_0???'), 871 ]); 872 }, 'incomingBidInSellerCurrency at top-level doing a no-op conversion OK.'); 873 874 // TODO: PrivateAggregation. It follows the same rules as 875 // highestScoringOtherBid, but is actually visible at top-level.