tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

interest-group-passed-to-generate-bid.https.window.js (24218B)


      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-5
      8 // META: variant=?6-10
      9 // META: variant=?11-15
     10 // META: variant=?16-20
     11 // META: variant=?21-25
     12 // META: variant=?26-30
     13 // META: variant=?31-35
     14 // META: variant=?36-40
     15 // META: variant=?41-45
     16 // META: variant=?46-50
     17 // META: variant=?51-55
     18 // META: variant=?56-60
     19 // META: variant=?61-65
     20 // META: variant=?66-70
     21 // META: variant=?71-75
     22 // META: variant=?76-80
     23 // META: variant=?81-85
     24 
     25 "use strict";
     26 
     27 // These tests focus on making sure InterestGroup fields are passed to generateBid(),
     28 // and are normalized if necessary. This test does not check the behaviors of the
     29 // fields.
     30 
     31 // Modifies "ads". Replaces "REPLACE_WITH_UUID" in all "renderURL" fields of
     32 // objects in "ads" array with "uuid". Generated ad URLs have embedded
     33 // UUIDs to prevent InterestGroups unexpectedly left over from one test from
     34 // messing up another test, but these tests need ad URLs before the UUID is
     35 // generated. To get around that, "REPLACE_WITH_UUID" is used in place of UUIDs
     36 // and then this is used to replace them with the real UUID.
     37 function updateAdRenderURLs(ads, uuid) {
     38  for (let i = 0; i < ads.length; ++i) {
     39    let ad = ads[i];
     40    ad.renderURL = ad.renderURL.replace('REPLACE_WITH_UUID', uuid);
     41  }
     42 }
     43 
     44 const makeTest = ({
     45  // Test name.
     46  name,
     47  // InterestGroup field name.
     48  fieldName,
     49  // InterestGroup field value, both expected in worklets and the value used
     50  // when joining the interest group. If undefined, value will not be set in
     51  // interestGroup, and will be expected to also not be set in the
     52  // interestGroup passed to generateBid().
     53  fieldValue,
     54  // Additional values to use in the InterestGroup passed to joinInterestGroup().
     55  // If it contains a value for the key specified in `fieldName`, takes
     56  // precedent over `fieldValue`.
     57  interestGroupOverrides = {}
     58 }) => {
     59  subsetTest(promise_test, async test => {
     60    const uuid = generateUuid(test);
     61 
     62    // It's not strictly necessary to replace UUIDs in "adComponents", but do it for consistency.
     63    if (fieldName === 'ads' || fieldName === 'adComponents' && fieldValue) {
     64      updateAdRenderURLs(fieldValue, uuid);
     65    }
     66 
     67    if (interestGroupOverrides.ads) {
     68      updateAdRenderURLs(interestGroupOverrides.ads, uuid);
     69    }
     70 
     71    if (interestGroupOverrides.adComponents) {
     72      updateAdRenderURLs(interestGroupOverrides.adComponents, uuid);
     73    }
     74 
     75    if (!(fieldName in interestGroupOverrides) && fieldValue !== undefined)
     76      interestGroupOverrides[fieldName] = fieldValue;
     77 
     78    let comparison = `deepEquals(interestGroup["${fieldName}"], ${JSON.stringify(fieldValue)})`;
     79    // In the case it's undefined, require value not to be set.
     80    if (fieldValue === undefined)
     81      comparison = `!("${fieldName}" in interestGroup)`;
     82 
     83    // Prefer to use `interestGroupOverrides.owner` if present. Treat it as a URL
     84    // and then convert it to an origin because one test passes in a URL.
     85    let origin = location.origin;
     86    if (interestGroupOverrides.owner)
     87      origin = new URL(interestGroupOverrides.owner).origin;
     88 
     89    interestGroupOverrides.biddingLogicURL =
     90        createBiddingScriptURL(
     91            { origin: origin,
     92              generateBid:
     93                  `// Delete deprecated "renderUrl" fields from ads and adComponents, if
     94                  // present.
     95                  for (let field in interestGroup) {
     96                    if (field === "ads" || field === "adComponents") {
     97                      for (let i = 0; i < interestGroup[field].length; ++i) {
     98                        let ad = interestGroup[field][i];
     99                        delete ad.renderUrl;
    100                      }
    101                    }
    102                  }
    103                  if (!${comparison})
    104                    throw "Unexpected value: " + JSON.stringify(interestGroup["${fieldName}"]);`
    105            });
    106    if (origin !== location.origin) {
    107      await joinCrossOriginInterestGroup(test, uuid, origin, interestGroupOverrides);
    108    } else {
    109      await joinInterestGroup(test, uuid, interestGroupOverrides);
    110    }
    111 
    112    await runBasicFledgeTestExpectingWinner(test, uuid, {interestGroupBuyers: [origin]});
    113  }, name);
    114 };
    115 
    116 makeTest({
    117  name: 'InterestGroup.owner.',
    118  fieldName: 'owner',
    119  fieldValue: OTHER_ORIGIN1
    120 });
    121 
    122 makeTest({
    123  name: 'InterestGroup.owner with non-normalized origin.',
    124  fieldName: 'owner',
    125  fieldValue: OTHER_ORIGIN1,
    126  interestGroupOverrides: {owner: ` ${OTHER_ORIGIN1.toUpperCase()} `}
    127 });
    128 
    129 makeTest({
    130  name: 'InterestGroup.owner is URL.',
    131  fieldName: 'owner',
    132  fieldValue: OTHER_ORIGIN1,
    133  interestGroupOverrides: {owner: OTHER_ORIGIN1 + '/Foopy'}
    134 });
    135 
    136 makeTest({
    137  name: 'InterestGroup.name.',
    138  fieldName: 'name',
    139  fieldValue: 'Jim'
    140 });
    141 
    142 makeTest({
    143  name: 'InterestGroup.name with unicode characters.',
    144  fieldName: 'name',
    145  fieldValue: '\u2665'
    146 });
    147 
    148 makeTest({
    149  name: 'InterestGroup.name with empty name.',
    150  fieldName: 'name',
    151  fieldValue: ''
    152 });
    153 
    154 makeTest({
    155  name: 'InterestGroup.name with unpaired surrogate characters, which should be replaced with "\\uFFFD".',
    156  fieldName: 'name',
    157  fieldValue: '\uFFFD,\uFFFD',
    158  interestGroupOverrides: {name: '\uD800,\uDBF0'}
    159 });
    160 
    161 // Since "biddingLogicURL" contains the script itself inline, can't include the entire URL
    162 // in the script for an equality check. Instead, replace the "generateBid" query parameter
    163 // in the URL with an empty value before comparing it. This doesn't just delete the entire
    164 // query parameter to make sure that's correctly passed in.
    165 subsetTest(promise_test,async test => {
    166  const uuid = generateUuid(test);
    167 
    168  let biddingScriptBaseURL = createBiddingScriptURL({origin: OTHER_ORIGIN1, generateBid: ''});
    169  let biddingLogicURL = createBiddingScriptURL(
    170      { origin: OTHER_ORIGIN1,
    171        generateBid:
    172          `let biddingScriptBaseURL =
    173            interestGroup.biddingLogicURL.replace(/generateBid=[^&]*/, "generateBid=");
    174          if (biddingScriptBaseURL !== "${biddingScriptBaseURL}")
    175            throw "Wrong bidding script URL: " + interestGroup.biddingLogicURL`
    176      });
    177 
    178  await joinCrossOriginInterestGroup(test, uuid, OTHER_ORIGIN1,
    179                                     { biddingLogicURL: biddingLogicURL });
    180 
    181  await runBasicFledgeTestExpectingWinner(test, uuid, {interestGroupBuyers: [OTHER_ORIGIN1]});
    182 }, 'InterestGroup.biddingLogicURL.');
    183 
    184 // Much like above test, but use a relative URL that points to bidding script.
    185 subsetTest(promise_test,async test => {
    186  const uuid = generateUuid(test);
    187 
    188  let biddingScriptBaseURL = createBiddingScriptURL({generateBid: ''});
    189  let biddingLogicURL = createBiddingScriptURL(
    190      { generateBid:
    191          `let biddingScriptBaseURL =
    192            interestGroup.biddingLogicURL.replace(/generateBid=[^&]*/, "generateBid=");
    193          if (biddingScriptBaseURL !== "${biddingScriptBaseURL}")
    194            throw "Wrong bidding script URL: " + interestGroup.biddingLogicURL`
    195      });
    196  biddingLogicURL = biddingLogicURL.replace(BASE_URL, 'foo/../');
    197 
    198  await joinInterestGroup(test, uuid, { biddingLogicURL: biddingLogicURL });
    199 
    200  await runBasicFledgeTestExpectingWinner(test, uuid);
    201 }, 'InterestGroup.biddingLogicURL with relative URL.');
    202 
    203 makeTest({
    204  name: 'InterestGroup.lifetimeMs should not be passed in.',
    205  fieldName: 'lifetimeMs',
    206  fieldValue: undefined,
    207  interestGroupOverrides: { lifetimeMs: "120000" }
    208 });
    209 
    210 makeTest({
    211  name: 'InterestGroup.priority should not be passed in, since it can be changed by auctions.',
    212  fieldName: 'priority',
    213  fieldValue: undefined,
    214  interestGroupOverrides: { priority: 500 }
    215 });
    216 
    217 makeTest({
    218  name: 'InterestGroup.priorityVector undefined.',
    219  fieldName: 'priorityVector',
    220  fieldValue: undefined
    221 });
    222 
    223 makeTest({
    224  name: 'InterestGroup.priorityVector empty.',
    225  fieldName: 'priorityVector',
    226  fieldValue: {}
    227 });
    228 
    229 makeTest({
    230  name: 'InterestGroup.priorityVector.',
    231  fieldName: 'priorityVector',
    232  fieldValue: { 'a': -1, 'b': 2 }
    233 });
    234 
    235 // TODO: This is currently using USVString internally, so doesn't allow unpaired
    236 // surrogates, but the spec says it should.
    237 makeTest({
    238  name: 'InterestGroup.priorityVector with unpaired surrogate character.',
    239  fieldName: 'priorityVector',
    240  fieldValue: { '\uFFFD': -1 },
    241  interestGroupOverrides: { prioritySignalsOverrides: { '\uD800': -1 } }
    242 });
    243 
    244 makeTest({
    245  name: 'InterestGroup.prioritySignalsOverrides should not be passed in, since it can be changed by auctions.',
    246  fieldName: 'prioritySignalsOverrides',
    247  fieldValue: undefined,
    248  interestGroupOverrides: { prioritySignalsOverrides: { 'a': 1, 'b': 2 } }
    249 });
    250 
    251 makeTest({
    252  name: 'InterestGroup.enableBiddingSignalsPrioritization not set.',
    253  fieldName: 'enableBiddingSignalsPrioritization',
    254  fieldValue: false,
    255  interestGroupOverrides: { enableBiddingSignalsPrioritization: undefined }
    256 });
    257 
    258 makeTest({
    259  name: 'InterestGroup.enableBiddingSignalsPrioritization unrecognized.',
    260  fieldName: 'enableBiddingSignalsPrioritization',
    261  // Non-empty strings are treated as true by Javascript. This test is serves
    262  // to make sure that the 'foo' isn't preserved.
    263  fieldValue: true,
    264  interestGroupOverrides: { enableBiddingSignalsPrioritization: 'foo' }
    265 });
    266 
    267 makeTest({
    268  name: 'InterestGroup.enableBiddingSignalsPrioritization false.',
    269  fieldName: 'enableBiddingSignalsPrioritization',
    270  fieldValue: false
    271 });
    272 
    273 makeTest({
    274  name: 'InterestGroup.enableBiddingSignalsPrioritization true.',
    275  fieldName: 'enableBiddingSignalsPrioritization',
    276  fieldValue: true
    277 });
    278 
    279 makeTest({
    280  name: 'InterestGroup.biddingWasmHelperURL not set.',
    281  fieldName: 'biddingWasmHelperURL',
    282  fieldValue: undefined
    283 });
    284 
    285 makeTest({
    286  name: 'InterestGroup.biddingWasmHelperURL.',
    287  fieldName: 'biddingWasmHelperURL',
    288  fieldValue: `${OTHER_ORIGIN1}${RESOURCE_PATH}wasm-helper.py`,
    289  interestGroupOverrides: {owner: OTHER_ORIGIN1}
    290 });
    291 
    292 makeTest({
    293  name: 'InterestGroup.biddingWasmHelperURL with non-normalized value.',
    294  fieldName: 'biddingWasmHelperURL',
    295  fieldValue: `${OTHER_ORIGIN1}${RESOURCE_PATH}wasm-helper.py`,
    296  interestGroupOverrides: {
    297    owner: OTHER_ORIGIN1,
    298    biddingWasmHelperURL:
    299        `${OTHER_ORIGIN1.toUpperCase()}${RESOURCE_PATH}wasm-helper.py`
    300  }
    301 });
    302 
    303 makeTest({
    304  name: 'InterestGroup.biddingWasmHelperURL with relative URL.',
    305  fieldName: 'biddingWasmHelperURL',
    306  fieldValue: `${OTHER_ORIGIN1}${RESOURCE_PATH}wasm-helper.py`,
    307  interestGroupOverrides: {
    308    owner: OTHER_ORIGIN1,
    309    biddingWasmHelperURL: 'foo/../resources/wasm-helper.py'
    310  }
    311 });
    312 
    313 makeTest({
    314  name: 'InterestGroup.biddingWasmHelperURL with unpaired surrogate characters, which should be replaced with "\\uFFFD".',
    315  fieldName: 'biddingWasmHelperURL',
    316  fieldValue: (new URL(`${OTHER_ORIGIN1}${RESOURCE_PATH}wasm-helper.py?\uFFFD.\uFFFD`)).href,
    317  interestGroupOverrides: {
    318    owner: OTHER_ORIGIN1,
    319    biddingWasmHelperURL: `${OTHER_ORIGIN1}${RESOURCE_PATH}wasm-helper.py?\uD800.\uDBF0`
    320  }
    321 });
    322 
    323 makeTest({
    324  name: 'InterestGroup.updateURL not set.',
    325  fieldName: 'updateURL',
    326  fieldValue: undefined
    327 });
    328 
    329 makeTest({
    330  name: 'InterestGroup.updateURL.',
    331  fieldName: 'updateURL',
    332  fieldValue: `${OTHER_ORIGIN1}${BASE_PATH}This-File-Does-Not-Exist.json`,
    333  interestGroupOverrides: {owner: OTHER_ORIGIN1}
    334 });
    335 
    336 makeTest({
    337  name: 'InterestGroup.updateURL with non-normalized value.',
    338  fieldName: 'updateURL',
    339  fieldValue: `${OTHER_ORIGIN1}${BASE_PATH}This-File-Does-Not-Exist.json`,
    340  interestGroupOverrides: {
    341    owner: OTHER_ORIGIN1,
    342    updateURL: `${OTHER_ORIGIN1.toUpperCase()}${BASE_PATH}This-File-Does-Not-Exist.json`
    343  }
    344 });
    345 
    346 makeTest({
    347  name: 'InterestGroup.updateURL with relative URL.',
    348  fieldName: 'updateURL',
    349  fieldValue: (new URL(`${OTHER_ORIGIN1}${BASE_PATH}../This-File-Does-Not-Exist.json`)).href,
    350  interestGroupOverrides: {
    351    owner: OTHER_ORIGIN1,
    352    updateURL: '../This-File-Does-Not-Exist.json'
    353  }
    354 });
    355 
    356 makeTest({
    357  name: 'InterestGroup.updateURL with unpaired surrogate characters, which should be replaced with "\\uFFFD".',
    358  fieldName: 'updateURL',
    359  fieldValue: (new URL(`${BASE_URL}\uFFFD.\uFFFD`)).href,
    360  interestGroupOverrides: {
    361    updateURL: `${BASE_URL}\uD800.\uDBF0`
    362  }
    363 });
    364 
    365 makeTest({
    366  name: 'InterestGroup.executionMode not present.',
    367  fieldName: 'executionMode',
    368  fieldValue: 'compatibility',
    369  interestGroupOverrides: { executionMode: undefined }
    370 });
    371 
    372 makeTest({
    373  name: 'InterestGroup.executionMode compatibility.',
    374  fieldName: 'executionMode',
    375  fieldValue: 'compatibility'
    376 });
    377 
    378 makeTest({
    379  name: 'InterestGroup.executionMode frozen-context.',
    380  fieldName: 'executionMode',
    381  fieldValue: 'frozen-context'
    382 });
    383 
    384 makeTest({
    385  name: 'InterestGroup.executionMode group-by-origin.',
    386  fieldName: 'executionMode',
    387  fieldValue: 'group-by-origin'
    388 });
    389 
    390 makeTest({
    391  name: 'InterestGroup.executionMode has non-standard string.',
    392  fieldName: 'executionMode',
    393  fieldValue: 'compatibility',
    394  interestGroupOverrides: { executionMode: 'foo' }
    395 });
    396 
    397 makeTest({
    398  name: 'InterestGroup.trustedBiddingSignalsURL not set.',
    399  fieldName: 'trustedBiddingSignalsURL',
    400  fieldValue: undefined
    401 });
    402 
    403 makeTest({
    404  name: 'InterestGroup.trustedBiddingSignalsURL.',
    405  fieldName: 'trustedBiddingSignalsURL',
    406  fieldValue: `${OTHER_ORIGIN1}${BASE_PATH}This-File-Does-Not-Exist.json`,
    407  interestGroupOverrides: {owner: OTHER_ORIGIN1}
    408 });
    409 
    410 makeTest({
    411  name: 'InterestGroup.trustedBiddingSignalsURL with non-normalized value.',
    412  fieldName: 'trustedBiddingSignalsURL',
    413  fieldValue: `${OTHER_ORIGIN1}${BASE_PATH}This-File-Does-Not-Exist.json`,
    414  interestGroupOverrides: {
    415    owner: OTHER_ORIGIN1,
    416    trustedBiddingSignalsURL:
    417        `${OTHER_ORIGIN1.toUpperCase()}${BASE_PATH}This-File-Does-Not-Exist.json`
    418  }
    419 });
    420 
    421 makeTest({
    422  name: 'InterestGroup.trustedBiddingSignalsURL with relative URL.',
    423  fieldName: 'trustedBiddingSignalsURL',
    424  fieldValue: (new URL(`${OTHER_ORIGIN1}${BASE_PATH}../This-File-Does-Not-Exist.json`)).href,
    425  interestGroupOverrides: {
    426    owner: OTHER_ORIGIN1,
    427    trustedBiddingSignalsURL: '../This-File-Does-Not-Exist.json'
    428  }
    429 });
    430 
    431 makeTest({
    432  name: 'InterestGroup.trustedBiddingSignalsURL with unpaired surrogate characters, which should be replaced with "\\uFFFD".',
    433  fieldName: 'trustedBiddingSignalsURL',
    434  fieldValue: (new URL(`${BASE_URL}\uFFFD.\uFFFD`)).href,
    435  interestGroupOverrides: {
    436    trustedBiddingSignalsURL: `${BASE_URL}\uD800.\uDBF0`
    437  }
    438 });
    439 
    440 makeTest({
    441  name: 'InterestGroup.trustedBiddingSignalsKeys not set.',
    442  fieldName: 'trustedBiddingSignalsKeys',
    443  fieldValue: undefined
    444 });
    445 
    446 makeTest({
    447  name: 'InterestGroup.trustedBiddingSignalsKeys.',
    448  fieldName: 'trustedBiddingSignalsKeys',
    449  fieldValue: ['a', ' b ', 'c', '1', '%20', '3', '\u2665']
    450 });
    451 
    452 makeTest({
    453  name: 'InterestGroup.trustedBiddingSignalsKeys with non-normalized values.',
    454  fieldName: 'trustedBiddingSignalsKeys',
    455  fieldValue: ['1', '2', '3'],
    456  interestGroupOverrides: { trustedBiddingSignalsKeys: [1, 0x2, '3'] }
    457 });
    458 
    459 makeTest({
    460  name: 'InterestGroup.trustedBiddingSignalsKeys unpaired surrogate characters, which should be replaced with "\\uFFFD".',
    461  fieldName: 'trustedBiddingSignalsKeys',
    462  fieldValue: ['\uFFFD', '\uFFFD', '\uFFFD.\uFFFD'],
    463  interestGroupOverrides: { trustedBiddingSignalsKeys: ['\uD800', '\uDBF0', '\uD800.\uDBF0'] }
    464 });
    465 
    466 makeTest({
    467  name: 'InterestGroup.trustedBiddingSignalsSlotSizeMode empty.',
    468  fieldName: 'trustedBiddingSignalsSlotSizeMode',
    469  fieldValue: 'none',
    470  interestGroupOverrides: { trustedBiddingSignalsSlotSizeMode: undefined }
    471 });
    472 
    473 makeTest({
    474  name: 'InterestGroup.trustedBiddingSignalsSlotSizeMode none.',
    475  fieldName: 'trustedBiddingSignalsSlotSizeMode',
    476  fieldValue: 'none'
    477 });
    478 
    479 makeTest({
    480  name: 'InterestGroup.trustedBiddingSignalsSlotSizeMode slot-size.',
    481  fieldName: 'trustedBiddingSignalsSlotSizeMode',
    482  fieldValue: 'slot-size'
    483 });
    484 
    485 makeTest({
    486  name: 'InterestGroup.trustedBiddingSignalsSlotSizeMode all-slots-requested-sizes.',
    487  fieldName: 'trustedBiddingSignalsSlotSizeMode',
    488  fieldValue: 'all-slots-requested-sizes'
    489 });
    490 
    491 makeTest({
    492  name: 'InterestGroup.trustedBiddingSignalsSlotSizeMode unrecognized value.',
    493  fieldName: 'trustedBiddingSignalsSlotSizeMode',
    494  fieldValue: 'none',
    495  interestGroupOverrides: { trustedBiddingSignalsSlotSizeMode: 'unrecognized value' }
    496 });
    497 
    498 makeTest({
    499  name: 'InterestGroup.userBiddingSignals not set.',
    500  fieldName: 'userBiddingSignals',
    501  fieldValue: undefined
    502 });
    503 
    504 makeTest({
    505  name: 'InterestGroup.userBiddingSignals is integer.',
    506  fieldName: 'userBiddingSignals',
    507  fieldValue: 15
    508 });
    509 
    510 makeTest({
    511  name: 'InterestGroup.userBiddingSignals is array.',
    512  fieldName: 'userBiddingSignals',
    513  fieldValue: [1, {a: 'b'}, 'c']
    514 });
    515 
    516 makeTest({
    517  name: 'InterestGroup.userBiddingSignals is object.',
    518  fieldName: 'userBiddingSignals',
    519  fieldValue: {a:1, b:32.5, c:['d', 'e']}
    520 });
    521 
    522 makeTest({
    523  name: 'InterestGroup.userBiddingSignals unpaired surrogate characters, which should be kept as-is.',
    524  fieldName: 'userBiddingSignals',
    525  fieldValue: '\uD800.\uDBF0'
    526 });
    527 
    528 makeTest({
    529  name: 'InterestGroup.userBiddingSignals unpaired surrogate characters in an object, which should be kept as-is.',
    530  fieldName: 'userBiddingSignals',
    531  fieldValue: {'\uD800': '\uDBF0', '\uDBF0':['\uD800']}
    532 });
    533 
    534 makeTest({
    535  name: 'InterestGroup.nonStandardField.',
    536  fieldName: 'nonStandardField',
    537  fieldValue: undefined,
    538  interestGroupOverrides: {nonStandardField: 'This value should not be passed to worklets'}
    539 });
    540 
    541 // Note that all ad tests have a deprecated "renderUrl" field passed to generateBid.
    542 
    543 // Ad URLs need the right UUID for seller scripts to accept their bids. Since UUID changes
    544 // for each test, and is not available outside makeTest(), have to use string that will
    545 // be replaced with the real UUID.
    546 const AD1_URL = createRenderURL('REPLACE_WITH_UUID', /*script=*/';');
    547 const AD2_URL = createRenderURL('REPLACE_WITH_UUID', /*script=*/';;');
    548 
    549 makeTest({
    550  name: 'InterestGroup.ads with one ad.',
    551  fieldName: 'ads',
    552  fieldValue: [{renderURL: AD1_URL}]
    553 });
    554 
    555 makeTest({
    556  name: 'InterestGroup.ads one ad with metadata object.',
    557  fieldName: 'ads',
    558  fieldValue: [{renderURL: AD1_URL, metadata: {foo: 1, bar: [2, 3], baz: '4'}}]
    559 });
    560 
    561 makeTest({
    562  name: 'InterestGroup.ads one ad with metadata string.',
    563  fieldName: 'ads',
    564  fieldValue: [{renderURL: AD1_URL, metadata: 'foo'}]
    565 });
    566 
    567 makeTest({
    568  name: 'InterestGroup.ads one ad with null metadata.',
    569  fieldName: 'ads',
    570  fieldValue: [{renderURL: AD1_URL, metadata: null}]
    571 });
    572 
    573 makeTest({
    574  name: 'InterestGroup.ads one ad with adRenderId. This field should not be passed to generateBid.',
    575  fieldName: 'ads',
    576  fieldValue: [{renderURL: AD1_URL}],
    577  interestGroupOverrides: {ads: [{renderURL: AD1_URL, adRenderId: 'twelve chars'}]}
    578 });
    579 
    580 makeTest({
    581  name: 'InterestGroup.ads one ad with buyerAndSellerReportingId. This field should not be passed to generateBid.',
    582  fieldName: 'ads',
    583  fieldValue: [{renderURL: AD1_URL}],
    584  interestGroupOverrides: {ads: [{renderURL: AD1_URL,
    585                                  buyerAndSellerReportingId: 'Arbitrary text'}]}
    586 });
    587 
    588 makeTest({
    589  name: 'InterestGroup.ads one ad with buyerReportingId. This field should not be passed to generateBid.',
    590  fieldName: 'ads',
    591  fieldValue: [{renderURL: AD1_URL}],
    592  interestGroupOverrides: {ads: [{renderURL: AD1_URL,
    593                                  buyerReportingId: 'Arbitrary text'}]}
    594 });
    595 
    596 makeTest({
    597  name: 'InterestGroup.ads one ad with novel field. This field should not be passed to generateBid.',
    598  fieldName: 'ads',
    599  fieldValue: [{renderURL: AD1_URL}],
    600  interestGroupOverrides: {ads: [{renderURL: AD1_URL, novelField: 'Foo'}]}
    601 });
    602 
    603 makeTest({
    604  name: 'InterestGroup.ads with multiple ads.',
    605  fieldName: 'ads',
    606  fieldValue: [{renderURL: AD1_URL, metadata: 1},
    607               {renderURL: AD2_URL, metadata: [2]}],
    608  interestGroupOverrides: {ads: [{renderURL: AD1_URL, metadata: 1},
    609                                 {renderURL: AD2_URL, metadata: [2]}]}
    610 });
    611 
    612 // This should probably be an error. This WPT test serves to encourage there to be a
    613 // new join-leave WPT test when that is fixed.
    614 makeTest({
    615  name: 'InterestGroup.ads duplicate ad.',
    616  fieldName: 'ads',
    617  fieldValue: [{renderURL: AD1_URL}, {renderURL: AD1_URL}],
    618  interestGroupOverrides: {ads: [{renderURL: AD1_URL}, {renderURL: AD1_URL}]}
    619 });
    620 
    621 makeTest({
    622  name: 'InterestGroup.adComponents is undefined.',
    623  fieldName: 'adComponents',
    624  fieldValue: undefined
    625 });
    626 
    627 // This one is likely a bug.
    628 makeTest({
    629  name: 'InterestGroup.adComponents is empty array.',
    630  fieldName: 'adComponents',
    631  fieldValue: undefined,
    632  interestGroupOverrides: {adComponents: []}
    633 });
    634 
    635 makeTest({
    636  name: 'InterestGroup.adComponents with one ad.',
    637  fieldName: 'adComponents',
    638  fieldValue: [{renderURL: AD1_URL}]
    639 });
    640 
    641 makeTest({
    642  name: 'InterestGroup.adComponents one ad with metadata object.',
    643  fieldName: 'adComponents',
    644  fieldValue: [{renderURL: AD1_URL, metadata: {foo: 1, bar: [2, 3], baz: '4'}}]
    645 });
    646 
    647 makeTest({
    648  name: 'InterestGroup.adComponents one ad with metadata string.',
    649  fieldName: 'adComponents',
    650  fieldValue: [{renderURL: AD1_URL, metadata: 'foo'}]
    651 });
    652 
    653 makeTest({
    654  name: 'InterestGroup.adComponents one ad with null metadata.',
    655  fieldName: 'adComponents',
    656  fieldValue: [{renderURL: AD1_URL, metadata: null}]
    657 });
    658 
    659 makeTest({
    660  name: 'InterestGroup.adComponents one ad with adRenderId. This field should not be passed to generateBid.',
    661  fieldName: 'adComponents',
    662  fieldValue: [{renderURL: AD1_URL}],
    663  interestGroupOverrides: {adComponents: [{renderURL: AD1_URL,
    664                                           adRenderId: 'twelve chars'}]}
    665 });
    666 
    667 makeTest({
    668  name: 'InterestGroup.adComponents one ad with buyerAndSellerReportingId. This field should not be passed to generateBid.',
    669  fieldName: 'adComponents',
    670  fieldValue: [{renderURL: AD1_URL}],
    671  interestGroupOverrides: {adComponents: [{renderURL: AD1_URL,
    672                                           buyerAndSellerReportingId: 'Arbitrary text'}]}
    673 });
    674 
    675 makeTest({
    676  name: 'InterestGroup.adComponents one ad with buyerReportingId. This field should not be passed to generateBid.',
    677  fieldName: 'adComponents',
    678  fieldValue: [{renderURL: AD1_URL}],
    679  interestGroupOverrides: {adComponents: [{renderURL: AD1_URL,
    680                                           buyerReportingId: 'Arbitrary text'}]}
    681 });
    682 
    683 makeTest({
    684  name: 'InterestGroup.adComponents one ad with novel field. This field should not be passed to generateBid.',
    685  fieldName: 'adComponents',
    686  fieldValue: [{renderURL: AD1_URL}],
    687  interestGroupOverrides: {adComponents: [{renderURL: AD1_URL,
    688                                           novelField: 'Foo'}]}
    689 });
    690 
    691 makeTest({
    692  name: 'InterestGroup.adComponents with multiple ads.',
    693  fieldName: 'adComponents',
    694  fieldValue: [{renderURL: AD1_URL, metadata: 1}, {renderURL: AD2_URL, metadata: [2]}]
    695 });
    696 
    697 makeTest({
    698  name: 'InterestGroup.auctionServerRequestFlags is undefined',
    699  fieldName: 'auctionServerRequestFlags',
    700  fieldValue: undefined
    701 });
    702 
    703 makeTest({
    704  name: 'InterestGroup.auctionServerRequestFlags is "omit-ads".',
    705  fieldName: 'auctionServerRequestFlags',
    706  fieldValue: undefined,
    707  interestGroupOverrides: {auctionServerRequestFlags: ['omit-ads']}
    708 });
    709 
    710 makeTest({
    711  name: 'InterestGroup.auctionServerRequestFlags is "include-full-ads".',
    712  fieldName: 'auctionServerRequestFlags',
    713  fieldValue: undefined,
    714  interestGroupOverrides: {auctionServerRequestFlags: ['include-full-ads']}
    715 });
    716 
    717 makeTest({
    718  name: 'InterestGroup.auctionServerRequestFlags has multiple values.',
    719  fieldName: 'auctionServerRequestFlags',
    720  fieldValue: undefined,
    721  interestGroupOverrides: {auctionServerRequestFlags: ['omit-ads', 'include-full-ads']}
    722 });
    723 
    724 makeTest({
    725  name: 'InterestGroup.auctionServerRequestFlags.',
    726  fieldName: 'auctionServerRequestFlags',
    727  fieldValue: undefined,
    728  interestGroupOverrides: {auctionServerRequestFlags: ['noval value']}
    729 });
    730 
    731 // This should probably be an error. This WPT test serves to encourage there to be a
    732 // new join-leave WPT test when that is fixed.
    733 makeTest({
    734  name: 'InterestGroup.adComponents duplicate ad.',
    735  fieldName: 'adComponents',
    736  fieldValue: [{renderURL: AD1_URL}, {renderURL: AD1_URL}],
    737  interestGroupOverrides: {adComponents: [{renderURL: AD1_URL}, {renderURL: AD1_URL}]}
    738 });