tor-browser

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

test-case.sub.js (4176B)


      1 function TestCase(scenarios, sanityChecker) {
      2  function runTest(scenario) {
      3    sanityChecker.checkScenario(scenario, subresourceMap);
      4 
      5    const urls = getRequestURLs(scenario.subresource,
      6                                scenario.origin,
      7                                scenario.redirection);
      8 
      9    /** @type {Subresource} */
     10    const subresource = {
     11      subresourceType: scenario.subresource,
     12      url: urls.testUrl,
     13      policyDeliveries: scenario.subresource_policy_deliveries,
     14    };
     15 
     16    let violationEventResolve;
     17    // Resolved with an array of securitypolicyviolation events.
     18    const violationEventPromise = new Promise(resolve => {
     19        violationEventResolve = resolve;
     20      });
     21 
     22    promise_test(async t => {
     23      await xhrRequest(urls.announceUrl);
     24 
     25      // Currently only requests from top-level Documents are tested
     26      // (specified by `spec.src.json`) and thus securitypolicyviolation
     27      // events are assumed to be fired on the top-level Document here.
     28      // When adding non-top-level Document tests, securitypolicyviolation
     29      // events should be caught in appropriate contexts.
     30      const violationEvents = [];
     31      const listener = e => { violationEvents.push(e); };
     32      document.addEventListener('securitypolicyviolation', listener);
     33 
     34      try {
     35        // Send out the real resource request.
     36        // This should tear down the key if it's not blocked.
     37        const mainPromise = invokeRequest(subresource, scenario.source_context_list);
     38        if (scenario.expectation === 'allowed') {
     39          await mainPromise;
     40        } else {
     41          await mainPromise
     42              .then(t.unreached_func('main promise resolved unexpectedly'))
     43              .catch(_ => {});
     44        }
     45      } finally {
     46        // Always perform post-processing/clean up for
     47        // 'securitypolicyviolation' events and resolve
     48        // `violationEventPromise`, to prevent timeout of the
     49        // promise_test() below.
     50 
     51        // securitypolicyviolation events are fired in a queued task in
     52        // https://w3c.github.io/webappsec-csp/#report-violation
     53        // so wait for queued tasks to run using setTimeout().
     54        let timeout = 0;
     55        if (scenario.subresource.startsWith('worklet-') &&
     56            navigator.userAgent.includes("Firefox/")) {
     57          // https://bugzilla.mozilla.org/show_bug.cgi?id=1808911
     58          // In Firefox sometimes violations from Worklets are delayed.
     59          timeout = 10;
     60        } else if (scenario.subresource.startsWith('worker-') &&
     61                   navigator.userAgent.includes("Servo/")) {
     62          // In Servo, worker violations are also delayed, as they are
     63          // sent via IPC. However, they typically arrive relatively
     64          // quickly after that.
     65          timeout = 1;
     66        }
     67        await new Promise(resolve => setTimeout(resolve, timeout));
     68 
     69        // Pass violation events to `violationEventPromise` (which will be tested
     70        // in the subsequent promise_test()) and clean up the listener.
     71        violationEventResolve(violationEvents);
     72        document.removeEventListener('securitypolicyviolation', listener);
     73      }
     74 
     75      // Send request to check if the key has been torn down.
     76      const assertResult = await xhrRequest(urls.assertUrl);
     77 
     78      // Now check if the value has been torn down. If it's still there,
     79      // we have blocked the request by content security policy.
     80      assert_equals(assertResult.status, scenario.expectation,
     81        "The resource request should be '" + scenario.expectation + "'.");
     82 
     83    }, scenario.test_description);
     84 
     85    promise_test(async _ => {
     86        const violationEvents = await violationEventPromise;
     87        if (scenario.expectation === 'allowed') {
     88          assert_array_equals(violationEvents, [],
     89              'no violation events should be fired');
     90        } else {
     91          assert_equals(violationEvents.length, 1,
     92              'One violation event should be fired');
     93        }
     94      }, scenario.test_description + ": securitypolicyviolation");
     95  }  // runTest
     96 
     97  function runTests() {
     98    for (const scenario of scenarios) {
     99      runTest(scenario);
    100    }
    101  }
    102 
    103  return {start: runTests};
    104 }